使用表达式传递属性作为参考

发布于 10-28 20:10 字数 943 浏览 4 评论 0原文

这篇文章详细介绍了将属性作为引用传递的解决方法,包括使用诸如

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

此方法之 类的表达式没问题,我注意到许多框架似乎都使用这个(例如 automapper、autofac),详见 James Gregory 的 静态反射简介,他指出

这样做的好处是,如果您更改 lambda 内的成员名称,并且尚未更新所有引用,您将收到编译错误!不再有隐藏的错误。

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

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

目前是否有更好的方法来引用属性(通过锁定表达式,或其他方式)

如果否,C# 的未来版本将如何锁定表达式?例如,类似:

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

澄清:上面只是一个示例,我知道目前不支持此功能;这就是我想讨论的。

This post details workarounds for passing properties as references including using Expressions such as

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

This approach is ok and I note many frameworks appear to use this (eg automapper, autofac) as detailed in James Gregory's Introduction to static reflection where he states

The great thing about this is that if you change the name of a member inside a lambda, you’ll get a compile error if you haven’t updated all the references! No more hidden bugs.

Whilst I much prefer this approach it is still not perfect as you can pass any expression returning an object (or whatever your return val is) eg

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

Is there currently any better way to reference the property (by locking down the Expression, or some other way)

If No, how might a future version of C# lock down the Expression? for example, something like:

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

clarification: above is only an example, I know this isn't currently supported; thats what I'm trying to discuss.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请帮我爱他2024-11-04 20:10:15

好吧,我不明白这怎么可能。

我不会说这是“令人愤慨的”建议,这根本不是预期用途。
事实上,整个概念虽然在这种情况下非常有用,但并不是为了解决这种情况而设计的。 LINQ 旨在作为一种具有丰富表达机制的可扩展查询语言。
Linq 扩展了语言语法,以允许在所提供的类型上使用强的、类型安全的表达式,这就是为什么您可以通过这种方式使用它来获得强的、类型安全的表达式。

在本例中,您将创建一个函数,将一种数据类型(T 对象)转换为另一种数据类型(通用对象)。
如果我被禁止编写诸如 p=>p.Name+"something" 这样的东西,我将失去该语言的许多固有灵活性。
即,作为返回元素总和的某些查询结果,这是不可能的p=>pX + pY

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

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

Well, i don't see how it would be possible.

I wouldn't say it's "outrageous" to suggest, it's simply not the intended use.
In fact this whole concept, while very useful in this situation, was not designed to answer this case. LINQ was intended as an extendable query language with a rich expression mechanism.
Linq extends the language syntax to allow strong, type-safe expressions on the provided types and this is why you can use it in this way to get a strong and typesafe expression.

In this case, you are creating a function that transforms one data type (the T object) into another - a general object.
If i was prohibited from writing something like p=>p.Name+"something" i would lose a lot of the inherent flexibility of the language.
I.e. This would not be possible p=>p.X + p.Y as some query result that returns a sum of elements.

The solution you showed is designed to utilize a feature of linq - strong, type safe property names. It provides an elegant way of using linq to solve a problem, but like any solution - it is open to possible abuse.

A developer that passes p=>p.Name+"something" did not grok the intended use of the solution, which is a matter for training.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文