代码之家  ›  专栏  ›  技术社区  ›  Rob

表达式<Func<TModel,TProperty>>作为对象初始化的属性?

  •  5
  • Rob  · 技术社区  · 14 年前

    我的表达式不太好,我想对它们进行改进,因此我想知道是否有人可以为我解释是否可以在类中创建一个属性,该属性可以在这样的实例化过程中被赋予一个值:

    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; }
    }
    

    它背后的基本思想是,我从一堆列对象创建一个网格,就像这样。

    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 回复  |  直到 14 年前
        1
  •  8
  •   idursun    14 年前

    当你定义 Func<TModel, TProperty> 这意味着有一个方法接受TModel类型并返回TProperty类型。所以lambda表达式

    p => p.ProductId 
    

    返回属性的值,而不是属性本身。

    您可以做的是定义 ColumnProperty 具体如下:

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

    然后可以从表达式树中提取详细信息。

        2
  •  1
  •   Rob    14 年前

    好吧,我只是灵机一动,把t属性改为dynamic,现在我可以这么做了,所以我想我回答了自己的问题,但我希望其他人能考虑一下这种方法的利弊:

    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);
    }