简体   繁体   中英

Linq Expressions -> Create CallExpression with Equals using enum types

I'm trying to build an CallExpression like:

f.Equals(s);

where, f and t are enum SType .

So,

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);

I don't know, but equalsMethod is Boolean Equals(System.Object) instead of Boolean Equals(SType) .

So, when I want to build CallExpression .Net tells me, I'm not able to use an expression of type SType for the parameter of type System.Object of the method Boolean Equals(System.Object) .

What's wrong?

When you call f.Equals(s) you're really doing:

f.Equals((object)s)

... because Enum and ValueType don't overload Equals . So basically you need a conversion in there - and you can be clearer about the Equals method you're calling, too:

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);

Admittedly you could probably avoid the separate step, just with:

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);

I haven't tried that, but I suspect it will work just fine.

Jon already described what's wrong with your code. However, I'm wondering why you ever bother creating MethodCallExpression to Equals method while there is a specific Expression.Equal method just for that (well, to be precise, for doing equality comparison):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM