[英]How to prevent Convert in generated expression for type parameter is interface
Here is the example code:这是示例代码:
public interface A
{
int MyProperty { get; set; }
}
public class B : A
{
public int MyProperty { get; set; }
}
public class C<T> where T : A
{
public Expression<Func<T, bool>> Expression { get; } = a => a.MyProperty > 0;
}
class Program
{
static void Main(string[] args)
{
var cExpression = new C<B>();
Console.WriteLine(cExpression.Expression.ToString());
}
}
The output of the expression: a => (Convert(a, A).MyProperty > 0)
output 的表达式:
a => (Convert(a, A).MyProperty > 0)
And I decompiled the code above and I got below:我反编译了上面的代码,得到了下面的结果:
public class C<T> where T : A
{
public Expression<Func<T, bool>> Expression { get; } = (T a) => ((A)a).MyProperty > 0;
}
As you can see, the compiler added a cast option ((A)a)
to the expression, that is what I DO NOT want, so the question is how can I tell the compiler NOT to do that?如您所见,编译器在表达式中添加了一个强制转换选项
((A)a)
,这是我不想要的,所以问题是我如何告诉编译器不要这样做?
There is no way to "tell the compiler" not to do this, but you can construct the expression tree directly:没有办法“告诉编译器”不要这样做,但可以直接构造表达式树:
public class C<T> where T : A {
private static readonly MethodInfo s_propGetter = typeof(A).GetProperty(nameof(A.MyProperty)).GetMethod;
public Expression<Func<T, bool>> Expr { get; private set; }
public C() {
var param = Expression.Parameter(typeof(T), "a");
Expr = Expression.Lambda(
typeof(Func<T, bool>),
Expression.GreaterThan(Expression.Property(param, s_propGetter), Expression.Constant(0)),
new[] {param}
) as Expression<Func<T, bool>>;
}
}
Looks like the compiler is emitting the Convert
because of the possibility of the generic type parameter to be struct
(value type), even though the manual approach demonstrated by another answer proves that it is unnecessary.看起来编译器正在发出
Convert
,因为泛型类型参数可能是struct
(值类型),即使另一个答案演示的手动方法证明它是不必要的。
But is is what it is.但就是这样。 So the only way currently to tell compiler to not generate
Convert
(cast) is to put class
constraint:因此,目前告诉编译器不生成
Convert
(cast) 的唯一方法是放置class
约束:
where T : class, A
Now the output of the original sample expression will be a => (a.MyProperty > 0)
现在原始样本表达式的 output 将是
a => (a.MyProperty > 0)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.