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?

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow