使用表达式将属性作为引用传递

时间:2011-04-03 13:24:21

标签: c# .net expression-trees

This发布详细信息解决方法,将属性作为引用传递,包括使用表达式(如

  public void StoreProperty(Expression<Func<T, object>> expr)

这种方法还可以,我注意到许多框架似乎都使用了这个(例如,automapper,autofac),详见詹姆斯格雷戈里的Introduction to static reflection,其中陈述

  

关于这一点的好处是,如果你更改lambda中的成员名称,如果你没有更新所有引用,你将收到编译错误!没有更多隐藏的错误。

虽然我更喜欢这种方法但它仍然不完美,因为你可以传递任何表达式返回一个对象(或者你的返回值是什么),例如

 x => x.Name) //fine
 x => x.Name+"x")  //runtime error

目前有没有更好的方法来引用该属性(通过锁定Expression或其他方式)

如果否,未来的C#版本如何锁定Expression?例如,像:

public void StoreProperty(Expression<Func<T, object>> expr) where expr.Member is PropertyInfo

澄清:上面只是一个例子,我知道目前不支持;这就是我想要讨论的内容。

1 个答案:

答案 0 :(得分:2)

好吧,我不知道怎么可能。

我不会说它是“令人发指的”建议,它根本不是预期的用途。 实际上,这个整体概念虽然在这种情况下非常有用,但并不是为了回答这个案例而设计的。 LINQ旨在作为具有丰富表达机制的可扩展查询语言。 Linq扩展了语言语法,允许在提供的类型上使用强类型安全表达式,这就是为什么你可以用这种方式来获得强大的类型安全表达式。

在这种情况下,您正在创建一个将一种数据类型(T对象)转换为另一种数据类型的函数 - 一般对象。 如果我被禁止写p=>p.Name+"something"这样的东西,我会失去语言固有的灵活性。 即这不可能是p=>p.X + p.Y,因为某些查询结果会返回元素的总和。

您展示的解决方案旨在利用linq的功能 - 强大的,类型安全的属性名称。它提供了一种使用linq来解决问题的优雅方式,但是就像任何解决方案一样 - 它可能会被滥用。

通过p=>p.Name+"something"的开发人员没有理解解决方案的预期用途,这是培训的问题。