我需要将所有属性映射到Func。我该怎么办?
我上课
class A
{
public int SomeIntValue { get; }
public string SomeStringValue { get; }
public Dictionary<...> SomeDictionary { get; }
}
和字典Dictionary<string, Func<A, object>>
。
我正在尝试为getter方法创建委托,但我真的不知道该怎么做。
以这种方式,它是行不通的,并且为什么会这样。我需要间接地做,但是怎么做?
(Func<TType, object>) Delegate.CreateDelegate(typeof(Func<TType, object>), null, property.GetGetMethod())
答案 0 :(得分:2)
您遇到的问题是从Func<A, int>
到Func<A, object>
的转换不是保留表示的转换,因此不允许通过Func系列的声明中提供的方差修饰符来进行转换。代表。对于值类型,您需要添加一条额外的IL指令,这是装箱转换。下面我提供了一种解决方案,该解决方案生成一种动态方法以在必要时(即当返回值是值类型时)添加所需的指令。它也更有效,因为它直接调用该属性,而不是依靠反射来处理调用。
using System.Reflection.Emit;
public static Dictionary<string, Func<T, object>> GetGetMethods<T>()
{
var getMethods = new Dictionary<string, Func<T, object>>();
foreach (var prop in typeof(T).GetProperties())
{
Func<T, object> del;
if (prop.PropertyType.IsValueType)
{
var dynMethod = new DynamicMethod(string.Format("Dynamic_Get_{0}_{1}", typeof(T).Name, prop.Name), typeof(object), new[] { typeof(T) }, typeof(T).Module);
var ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Callvirt, prop.GetGetMethod());
ilGen.Emit(OpCodes.Box, prop.PropertyType);
ilGen.Emit(OpCodes.Ret);
del = (Func<T, object>)dynMethod.CreateDelegate(typeof(Func<T, object>));
}
else
{
del = (Func<T, object>)Delegate.CreateDelegate(typeof(Func<T, object>), null, prop.GetGetMethod());
}
getMethods[prop.Name] = del;
}
return getMethods;
}
答案 1 :(得分:1)
我想您可以使用方法组runApp
创建委托:
somePropertyInfo.GetValue
然后您可以将其放入字典中。
您不需要Func<A, object> del = somePropertyInfo.GetValue;
调用,因为GetGetMethod
将调用getter。该方法用于将属性作为GetValue
对象。在这里,您不需要MethodInfo
。