Linq表达式 - >使用枚举类型使用Equals创建CallExpression

时间:2016-05-04 10:46:10

标签: c# linq

我正在尝试构建CallExpression之类的:

f.Equals(s);

其中,ftenum SType

所以,

var equalsMethod = typeof(SType).GetMethod("Equals", new[] { typeof(SType) });
ConstantExpression constantExpression = Expression.Constant(value, typeof(SType));
var newBody = Expression.Call(expr.Body, equalsMethod, constantExpression);
return Expression.Lambda<Func<TEntity, bool>>(newBody, expr.Parameters);

我不知道,但equalsMethodBoolean Equals(System.Object)而不是Boolean Equals(SType)

因此,当我想构建CallExpression .Net告诉我时,我无法使用SType类型的表达式来表示System.Object类型的参数方法Boolean Equals(System.Object)

出了什么问题?

2 个答案:

答案 0 :(得分:2)

当你致电f.Equals(s)时,你真的在​​做:

f.Equals((object)s)

...因为EnumValueType不会超载Equals。所以基本上你需要在那里进行转换 - 你也可以更清楚地了解你所调用的Equals方法:

var equalsMethod = typeof(object).GetMethod("Equals", new[] { typeof(object) });
var constant = Expression.Constant(value, typeof(SType));
var boxed = Expression.Convert(constant, typeof(object));
var newBody = Expression.Call(expr.Body, equalsMethod, boxed);
return Expression.Lambda<Func<TEntity, bool>>(newBody, expr.Parameters);

诚然,您可以避免单独的步骤,只需:

var equalsMethod = typeof(object).GetMethod("Equals", new[] { typeof(object) });
// Let this do the boxing for you...
var constant = Expression.Constant(value, typeof(object));
var newBody = Expression.Call(expr.Body, equalsMethod, constant);
return Expression.Lambda<Func<TEntity, bool>>(newBody, expr.Parameters);

我没有尝试过,但我怀疑它会正常工作。

答案 1 :(得分:2)

Jon已经描述了你的代码有什么问题。但是,我想知道你为什么要费心创建MethodCallExpressionEquals方法,而有一个特定的Expression.Equal方法只是为了那个(确切地说,为了进行相等比较) ):

return Expression.Lambda<Func<TEntity, bool>>(
    Expression.Equal(expr.Body, Expression.Constant(value)),
    expr.Parameters);