Выражение <Func <TModel, TProperty >> as Свойство для инициализации объекта? - PullRequest
5 голосов
/ 22 ноября 2010

Мое выражение невелико, и я хотел бы улучшить их, поэтому мне интересно, может ли кто-нибудь объяснить мне, возможно ли создать свойство в классе, которому может быть присвоено значение при создании экземпляра, например:

new Column<Product>{ ColumnProperty = p => p.Title};

или, что еще лучше (но я думаю, что я настаиваю на этом)

new Column {ColumnProperty = p => p.Title};

с классом, подобным этому:

public class Column<TModel>
{
        public Expression<Func<TModel, TProperty>> ColumnProperty { get; set; }
}

Основная идея заключается в следующемчто я создаю Grid из набора объектов Column примерно так.

List<Product> productList = GetProductsFromDb();
List<Column> columnList = new List<Column>();

columnList.Add(new Column<Product> {ColumnProperty = p => p.ProductId, Heading = "Product Id"});
columnList.Add(new Column<Product> {ColumnProperty = p => p.Title, Heading = "Title"});

Grid myGrid = new Grid(productList, columnList);

Возможно, это не самый простой и простой способ сделать это, но мне интересно знать, можно ли это сделать так, как я хочучтобы улучшить мое понимание выражений, и мне нравится иметь возможность иметь строго типизированные значения вместо строковых литералов, с которыми гораздо приятнее работать.

Буду очень признателен за любые мысли, идеи, бессвязные выражения

Приветствия Роб

Ответы [ 2 ]

8 голосов
/ 22 ноября 2010

Когда вы определяете что-то вроде Func<TModel, TProperty>, это означает, что есть метод, который принимает тип TModel и возвращает тип TProperty. Так что лямбда-выражения вроде

p => p.ProductId 

возвращает значение свойства, а не самого свойства.

Что вы можете сделать, чтобы этот синтаксис работал, это определить ваш ColumnProperty следующим образом:

public Expression<Func<TModel, object>> ColumnProperty { get; set; }

Затем вы можете извлечь подробную информацию из дерева выражений.

1 голос
/ 22 ноября 2010

Хорошо, у меня просто возникла мозговая волна, и я изменил TProperty на динамический, и теперь я могу сделать это, поэтому, я думаю, я ответил на свой вопрос, но заинтересовался бы мнением других людей о плюсах / минусах этого подхода:

foreach(Product p in productList)
{
    var value = column.ColumnProperty.Compile().Invoke(p);
}

На самом деле

, если я изменю свою собственность на

public Func<TModel, dynamic> ColumnProperty { get; set; }

, я могу просто сделать:

foreach(Product p in productList)
{
    var value = column.ColumnProperty(p);
}
...