Почему некоторые свойства объекта UnaryExpression и другие MemberExpression? - PullRequest
69 голосов
/ 25 августа 2010

Действуя в ответ на мой Выберите свойство модели, используя лямбду, а не имя свойства строки вопрос, желая добавить свойства в коллекцию следующим образом:

var props = new ExportPropertyInfoCollection<JobCard>();
props.Include(model => model.BusinessInstallNumber).Title("Install No").Width(64).KeepZeroPadding(true);
props.Include(model => model.DeviceName).Title("Device").Width(70);
props.Include(model => model.DateRequested).Title("Request Date").Format("{0:dd/MM/yyyy}").Width(83);

Iнаписал следующий код в методе Include:

public class PropertyCollection<T>
{
    public void Include(Expression<Func<T, object>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression != null)
        {
            var pes = new ExportPropertyInfoBuilder {Property = new ExportPropertyInfo {Property = memberExpression.Member as PropertyInfo}};
            Properties.Add(pes.Property.Property.Name, pes.Property);
            return pes;
    }

Однако при запуске кода я обнаружил, что некоторые лямбды дали MemberExpression значений, как и ожидалось, а другие дали UnaryExpression значения.Мне пришлось изменить первую строку кода на следующую, прежде чем я смог добавить все свои свойства, используя лямбда-выражения:

var memberExpression = expression.Body as MemberExpression ?? ((UnaryExpression) expression.Body).Operand as MemberExpression;

Все свойства являются «простыми» типами, то есть string, DateTime, int, bool и т. Д.в бизнес-объекте POCO.Они украшены несколькими различными DataAnnotations атрибутами.

Почему некоторые из лямбд в моем примере дают значения MemberExpression и другие UnaryExpression значения?В моем примере первое UnaryExpression находится в третьей строке, свойство DateTime , но логические свойства также приводят к UnaryExpressions .

1 Ответ

57 голосов
/ 26 августа 2010

Мне кажется, я знаю, в чем проблема. Ваше выражение возвращает тип object.

Если вы измените это значение на Expression<Func<T, R>>, то тип возвращаемого значения должен быть правильно выведен, и UnaryExpression (что я предполагаю, что это какая-то операция с боксом) не должно происходить.

Обновление:

Подпись для Include должна быть:

public void Include<T, R>(Expression<Func<T, R>> expression)
...