получить свойство лямбда из имени свойства (где тип свойства может быть обнуляемым) - PullRequest
1 голос
/ 26 ноября 2009

Привет! Мне нужна функция со следующей подписью

Expression<Func<T, object>> GetPropertyLambda(string propertyName)

Я сделал несколько попыток, но проблема возникает, когда свойство обнуляется
это выглядит примерно так

ParameterExpression param = Expression.Parameter(typeof(T), "arg");

Expression member = Expression.Property(param, propertyName);

//this next section does conver if the type is wrong however
// when we get to Expression.Lambda it throws
Type typeIfNullable = Nullable.GetUnderlyingType(member.Type);
if (typeIfNullable != null)
{
    member = Expression.Convert(member, typeIfNullable);
}                       
return Expression.Lambda<Func<T, object>>(member, param);

Исключение составляет

Выражение типа 'System.Decimal' нельзя использовать для типа возврата 'System.Object'

Я бы действительно оценил некоторые идеи, а также почему это не работает, как ожидалось

Спасибо

1 Ответ

8 голосов
/ 28 ноября 2009

На самом деле я не думаю, что проблема связана с типами Nullable, а скорее с типами значений. Попробуйте свой метод со свойством типа decimal (не Nullable<decimal>): он не сможет работать так же.

Посмотрите, как создаются деревья выражений для значений и ссылочных типов (например, с использованием LinqPad)

  • Expression<Func<T, object>> lambda = x => x.AString; (ссылочный тип)
    => Тело это MemberExpression

  • Expression<Func<T, object>> lambda = x => x.ADecimal; (тип значения)
    => Тело является UnaryExpression с NodeType = Convert и Type = typeof(object), а его Operand является MemberExpression

Я немного изменил ваш метод, чтобы учесть это, и, похоже, он работает нормально:

ParameterExpression param = Expression.Parameter(typeof(T), "arg");

Expression member = Expression.Property(param, propertyName);

if (member.Type.IsValueType)
{
  member = Expression.Convert(member, typeof(object));
}

return Expression.Lambda<Func<T, object>>(member, param);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...