Это зависит от Type
из memberExpression
, что, в свою очередь, зависит от типа, к которому имеет доступ свойство.
Например, следующие работы:
void Main()
{
string propertyName = "ObjectProperty";
ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "x");
MemberExpression memberExpression = Expression.Property(parameterExpression, propertyName);
MethodCallExpression methodCall = Expression.Call(
typeof(Enumerable),
"Contains",
new Type[] { typeof(object) },
Expression.Constant(new Object[] { 1, 2, 3 }),
memberExpression
);
Console.WriteLine(Expression.Lambda<Func<T, bool>>(methodCall, parameterExpression).Compile()(new T()));
}
public class T
{
public object ObjectProperty => 2;
public int IntProperty => 4;
}
not:
void Main()
{
string propertyName = "IntProperty";
ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "x");
MemberExpression memberExpression = Expression.Property(parameterExpression, propertyName);
MethodCallExpression methodCall = Expression.Call(
typeof(Enumerable),
"Contains",
new Type[] { typeof(object) },
Expression.Constant(new Object[] { 1, 2, 3 }),
memberExpression
);
Console.WriteLine(Expression.Lambda<Func<T, bool>>(methodCall, parameterExpression).Compile()(new T()));
}
public class T
{
public object ObjectProperty => 2;
public int IntProperty => 4;
}
Вы можете использовать new Type[] { memberExpression.Type }
вместо new Type[] { typeof(object) }
, чтобы код адаптировался к типу свойства, хотя вам также потребуется тип выражения аргумента (вв этом случае совпадение Constant(new Object[] {...}
)).
Обратите внимание, что здесь можно выполнять неявное приведение только в том случае, если они являются ссылочными типами, производными от рассматриваемого типа (object
), поэтому свойство, возвращающее string
или Uri
было бы хорошо (хотя, очевидно, всегда ложно при проверке того, содержалось ли оно в массиве 1, 2, 3
), но свойство, которое вернуло int
, не является таковым, как преобразование бокса, а не приведение ссылки.