2016-12-05 53 views
1

繼答案履行在這兒的一部分,問題是一些額外的信息,在問題有望解決點仍然正確的簽名在getmethod階級使用帶有多個重載泛型方法需要委託參數

開始編輯

var curEntityPI = ctx.GetType().GetProperties().Where(pr => pr.Name == "Client").First(); Type curEntityType = curEntityPI.PropertyType.GetGenericArguments().First(); Type[] typeArgs = { curEntityType }; Type propertyManagerType = generic.MakeGenericType(typeArgs); var propertyManager = Activator.CreateInstance(propertyManagerType, new object[] {});

考慮到這一點,我不能在第一個答案顯示的相同方式使用closeMethod.Invoke,它是Func鍵和返回身體,我不知道該怎麼落實到位調用時

編輯完

應該採取什麼方法簽名的樣子來思考,我想援引該

DynamicPropertyManager<ThreeColumns>.CreateProperty<ThreeColumns, string>(
    "Four", 
    t => "Four", 
    null 
)); 

這個類相當於這裏找到http://putridparrot.com/blog/dynamically-extending-an-objects-properties-using-typedescriptor/

  1. 但我試圖用反射來做到這一點。我最努力的是 正在得到正確的方法超負荷。

  2. 我必須說實話,雖然我還沒有完全確定如何提供正確的參數,通過反射 拉姆達位兩種。

我要試試這個部分,但不知道FUNC位 會是什麼樣做MakeGenericMethod

Func<string> funcArg =() => { return "Four"; }; 

object[] args = { fieldOrPropertyName , funcArg, null }時等;

以上鍊接中的課程內容僅供參考。

public class DynamicPropertyManager<TTarget> : IDisposable 
{ 
    private readonly DynamicTypeDescriptionProvider provider; 
    private readonly TTarget target; 

    public DynamicPropertyManager() 
    { 
     Type type = typeof(TTarget); 

     provider = new DynamicTypeDescriptionProvider(type); 
     TypeDescriptor.AddProvider(provider, type); 
    } 

    public DynamicPropertyManager(TTarget target) 
    { 
     this.target = target; 

     provider = new DynamicTypeDescriptionProvider(typeof(TTarget)); 
     TypeDescriptor.AddProvider(provider, target); 
    } 

    public IList<PropertyDescriptor> Properties 
    { 
     get { return provider.Properties; } 
    } 

    public void Dispose() 
    { 
     if (ReferenceEquals(target, null)) 
     { 
      TypeDescriptor.RemoveProvider(provider, typeof(TTarget)); 
     } 
     else 
     { 
      TypeDescriptor.RemoveProvider(provider, target); 
     } 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getter, 
      Action<TTargetType, TPropertyType> setter, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getter, setter, attributes); 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty1<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getHandler, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getHandler, (t, p) => { }, attributes); 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getHandler, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getHandler, (t, p) => { }, attributes); 
    } 
} 

回答

1

反思與泛型一起工作得很好,但如何處理特定的目標非常上下文相關的,因爲有可能封閉,開放和部分關閉類型和方法。儘管如此,通過使用Linq很容易獲得你正在尋找的東西。看一看:大規模

// get type from somewhere 
var compileTimeUnknownType = Type.GetType("ThreeColumns"); 

if (compileTimeUnknownType == null) 
    throw new ArgumentException("compileTimeUnknownType"); 

var managerType = typeof (DynamicPropertyManager<>).MakeGenericType(compileTimeUnknownType); 

var createPropertyMethod = managerType.GetMethods().Single(x => 
{ 
    var p = x.GetParameters(); 
    var g = x.GetGenericArguments(); 
    return x.Name == "CreateProperty" && 
      p.Length == 3 && 
      g.Length == 2 && 
      p[0].ParameterType == typeof (string) && 
      p[1].ParameterType == typeof (Func<,>).MakeGenericType(g) && 
      p[2].ParameterType == typeof (Attribute[]); 
}); 

var closedMethod = createPropertyMethod.MakeGenericMethod(new[] {compileTimeUnknownType, typeof (string)}); 

var paramExpr = Expression.Parameter(compileTimeUnknownType, "arg"); 
var lambda = 
    Expression.Lambda(typeof (Func<,>).MakeGenericType(new[] {compileTimeUnknownType, typeof (string)}), 
     Expression.Constant("Four"), new List<ParameterExpression>() {paramExpr}).Compile(); 

var ret = closedMethod.Invoke(null, new object[] {"Four", lambda, null}); 
+0

嗨感謝您的回覆我覺得createPropertyMethod將工作的偉大,但我的問題是,我使用反射的原因是ThreeColumns類是未知的我,直到運行時。在我的情況下,我將屬性附加到的類實際上是另一個通過反射獲得的泛型類,然後使用類類型實例化PropertyManager實例。編輯 –

+0

我修改了代碼,現在'ThreeColumns'類型不能編譯時間參考了。 – thehennyy

+0

非常感謝您的關注。我會給它一個去,然後接受並投票up.your答案。你真的是一個救生員 –

相關問題