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.
See more on this question at Stackoverflow