C# 4.0 是否应该添加扩展属性?

17

我希望实现流畅的接口。例如,参见Channel9讨论。可能还需要添加索引属性。

你认为呢?这样做的优点是否超过了“语言杂乱”所带来的不便?


3
在这个主题上,我发现了Eric Lippert的这篇有趣的博客文章:http://blogs.msdn.com/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx - Jon
不要让那个链接传到敏捷布道者那里,他们会以最好的怪异艾尔风格ROTFLOL。你在一个功能上投入了大量工作,只有在它几乎完成之后才从主要消费者那里得到反馈,猜猜发生了什么? - Francisco Aquino
2020年8月更新:请查看这个 Stack Overflow 帖子:https://dev59.com/fnRB5IYBdhLWcg3wc280?rq=1 和这个 GitHub 问题单:https://github.com/dotnet/csharplang/issues/192。 - lightw8
13个回答

29

由于属性仅仅是方法的语法糖,因此我不明白为什么C#可以拥有扩展方法而没有扩展属性。


9

这是关于数据绑定的问题,假设我有一个用于绑定到我的UI的对象,并且我想根据该对象的其他属性来隐藏或显示它。我可以添加一个IsVisible或Visibility的扩展属性,并将该属性绑定到UI。

虽然无法绑定扩展方法,但能够为无法扩展的现有类型添加可绑定的属性可能非常有用。


是的,我也需要它用于数据绑定!!! - tbone
1
这是行不通的:数据绑定使用反射来获取绑定对象类型的属性。扩展属性将存在于任意第二个类型中,而绑定框架将对此一无所知。扩展方法(如果存在)和属性是编译时特性,没有运行时可发现性。 - Ben M
1
有替代方案(我知道我回复晚了,但刚看到这个答案),通过使用实现一些与数据绑定相关的接口的集合,您可以使集合添加更多可绑定属性。换句话说,通过向集合提供如何计算IsVisible属性的配方,您可以在网格或类似控件中进行绑定。当然,如果您想从文本框或类似控件进行绑定,您可能会遇到麻烦。 - Lasse V. Karlsen

6
在我的书中,扩展属性最重要的原因是在未拥有代码周围实现流畅接口模式。我构建了一个包装器来包装NHibernate会话,使其更易于使用,以便我可以执行类似逻辑的操作。
public bool IsInTransaction
{
    get { return _session.Is().Not.Null && _session.Is().InTransaction; }
}

这看起来非常愚蠢,因为除非我直接修改会话对象上的源代码,否则没有办法将Is插入为属性。


3

我不知道为什么不行。属性只是具有不同语法的getter/setter方法。


2
我认为扩展属性并不会像扩展方法那样有用。我发现自己大多数情况下使用属性来封装字段(经典的get;set;)或提供只读性(仅对私有、只读、构造函数设置字段进行get)。由于扩展无法访问私有成员,特别是对于“set;”,我真的看不出有什么意义。要做任何事情,“set;”都必须调用其他方法。然后你就会遇到属性抛出异常的问题。
由于扩展仅限于使用公共属性和方法,我发现使用实用程序类的代码更清晰易读。归根结底,我们使用扩展方法使LINQ看起来漂亮。为了防止开发人员做错事,我可以在我的LINQ中处理额外的(),坚持只使用扩展方法。

重点是不要处理额外的括号,这与任何其他语法糖的作用相同。 - alpav

1

这将是一个不错的功能,但我看到很多人说他们想要它用于数据绑定,但由于它使用反射,这是不可能的。


1

我想如果使用它们没有或只有最小的性能损失,那么它们会很棒。


1

看起来很容易被滥用。正如其他人所提到的那样,C#属性只是方法的语法糖。然而,将它们实现为属性具有某些含义:访问不会产生副作用,修改属性应该非常廉价。后者是至关重要的,因为似乎扩展属性几乎总是比传统属性更昂贵。


0

开发人员应该使用属性来组织名称层次结构,避免使用驼峰命名法或下划线连接的名称拼接。 例如,他们应该扩展字符串类以使用类似于“some str”.decode.url 的东西,而不是 HttpUtility.UrlDecode。 目前在 C# 中实现这一点的唯一方法是:"some str".decode().url


0

好的,请加上索引属性和静态扩展内容,因为我非常想要它们用于System.Console(这不是开玩笑!)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接