Nic*_*ldi 7 c# generics lambda
我想"包装"特定属性的getter函数,该属性是特定类型的一部分.我有一个抽象类,定义如下:
public abstract class MyAbstractClass<T> where T : MyType
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
好吧,假设我有一个类似下面的具体类:
public abstract class MyConcreteClass : MyAbstractClass<MyConcreteType>
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,应该返回getter方法的包装器的helper方法:
private Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property)
{
var instanceType = Expression.Parameter(property.DeclaringType, "i");
// Taking getter's "body".
var getterBody = Expression.Property(instanceType, property);
// Cast to a generic Object.
var body = Expression.TypeAs(getterBody, typeof(Object));
// Build the expression.
var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(body, instanceType);
return exp.Compile();
}
Run Code Online (Sandbox Code Playgroud)
就像预期的那样,我得到以下异常:
"MyConcreteClass"类型的ParameterExpression不能用于"MyAbstractClass <MyConcreteType>"类型的委托参数.
有没有办法"强迫"这种铸造?提前致谢.
svi*_*ick 12
如果我正确理解你的问题,你想创建一个像这样的lambda表达式:
Func<MyAbstractClass<T>, Object> f = i => ((MyConcreteClass)i).SomeProperty;
Run Code Online (Sandbox Code Playgroud)
除非您想提供哪个属性SomeProperty
作为参数.好吧,如果你想以编程方式构建该表达式,你必须完全相同:拥有表达式参数i
(类型MyAbstractClass<T>
),将其强制转换为MyConcreteClass
然后访问它的属性SomeProperty
.
public Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property)
{
var parameter = Expression.Parameter(typeof(MyAbstractClass<T>), "i");
var cast = Expression.TypeAs(parameter, property.DeclaringType);
var getterBody = Expression.Property(cast, property);
var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(
getterBody, parameter);
return exp.Compile();
}
Run Code Online (Sandbox Code Playgroud)
话虽如此,我完全不知道你为什么要这样做,所以你最好确定这是你想要做的事情,没有更好的办法去做你真正想做的事情.