在 class 上的 getmethod 中使用正确的签名,具有多个需要委托参数的重载泛型方法
correct signature to use in getmethod on class with multiple overloaded generic methods requiring delegate argument
在回答部分解决问题后,有一些附加信息有望解决仍存在的问题
开始编辑
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 和 return 正文调用时就位
结束编辑
反射的方法签名应该是什么样的,我正在尝试调用这个
的等价物
DynamicPropertyManager<ThreeColumns>.CreateProperty<ThreeColumns, string>(
"Four",
t => "Four",
null
));
在此 class 上找到 http://putridparrot.com/blog/dynamically-extending-an-objects-properties-using-typedescriptor/
但我正在尝试使用反射来做到这一点。我在挣扎什么
最多的是获得正确的方法重载。
老实说,我也不太确定如何通过反射为 lambda 位提供正确的参数
要么。
我打算部分尝试这个,但不知道 func 位是什么
在做 MakeGenericMethod
时看起来像
Func<string> funcArg = () => { return "Four"; };
object[] args = { fieldOrPropertyName , funcArg, null }
;
收录上述link中的class内容,供参考。
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);
}
}
反射和泛型可以很好地协同工作,但是如何实现特定目标在很大程度上取决于上下文,因为可能存在封闭、开放和部分封闭的类型和方法。尽管如此,使用 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});
在回答部分解决问题后,有一些附加信息有望解决仍存在的问题
开始编辑
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 和 return 正文调用时就位
结束编辑
反射的方法签名应该是什么样的,我正在尝试调用这个
的等价物DynamicPropertyManager<ThreeColumns>.CreateProperty<ThreeColumns, string>(
"Four",
t => "Four",
null
));
在此 class 上找到 http://putridparrot.com/blog/dynamically-extending-an-objects-properties-using-typedescriptor/
但我正在尝试使用反射来做到这一点。我在挣扎什么 最多的是获得正确的方法重载。
老实说,我也不太确定如何通过反射为 lambda 位提供正确的参数 要么。
我打算部分尝试这个,但不知道 func 位是什么 在做 MakeGenericMethod
时看起来像Func<string> funcArg = () => { return "Four"; };
object[] args = { fieldOrPropertyName , funcArg, null }
;
收录上述link中的class内容,供参考。
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);
}
}
反射和泛型可以很好地协同工作,但是如何实现特定目标在很大程度上取决于上下文,因为可能存在封闭、开放和部分封闭的类型和方法。尽管如此,使用 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});