我正在尝试构建CallExpression
之类的:
f.Equals(s);
其中,f
和t
为enum 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);
我不知道,但equalsMethod
是Boolean Equals(System.Object)
而不是Boolean Equals(SType)
。
因此,当我想构建CallExpression
.Net告诉我时,我无法使用SType
类型的表达式来表示System.Object
类型的参数方法Boolean Equals(System.Object)
。
出了什么问题?
答案 0 :(得分:2)
当你致电f.Equals(s)
时,你真的在做:
f.Equals((object)s)
...因为Enum
和ValueType
不会超载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已经描述了你的代码有什么问题。但是,我想知道你为什么要费心创建MethodCallExpression
到Equals
方法,而有一个特定的Expression.Equal
方法只是为了那个(确切地说,为了进行相等比较) ):
return Expression.Lambda<Func<TEntity, bool>>(
Expression.Equal(expr.Body, Expression.Constant(value)),
expr.Parameters);