接口不应该有属性?

时间:2009-06-09 20:45:11

标签: .net design-patterns oop

我的办公室同事今天告诉我,在界面中使用属性是不好的做法。他在一些我无法找到的MSDN文章中用红色表示(好吧我在google上尝试过几次,可能用错误的关键词)。他还告诉我,只有方法应该在界面中。 现在,我知道这不是严格的规则,因为很明显在.net中你可以在接口中创建属性签名并编译它。

但这是不是一个糟糕的做法/设计/ oop?为什么?

指出正确的文献或网络资源也会有所帮助。

由于

13 个答案:

答案 0 :(得分:19)

我从来没有遇到任何人提出这种说法,也没有找到任何合理的理由。 .NET框架充满了具有属性的接口。

答案 1 :(得分:18)

我也会在这里添加我的声音 - 我从来没有遇到过这个建议。属性实际上是一对get / set方法。

像所有其他设计决定一样。如果它天真有意义;如果它适用于正在设计的系统,如果它不会导致维护问题,如果它不会导致性能问题,那么就没有理由你不能这样做。

答案 2 :(得分:15)

有广泛认可的术语“代码气味”。我建议引入“程序员气味”的概念 - 如果有人坚持一些规则,但无法解释为什么 - 这是一种气味。你的同事应该能够解释为什么界面中的属性是坏的。如果他不能 - 即使他所指的文章是正确的,他也可能是错的。

那篇文章可能是在讨论某些特定类型的接口,可能与COM和互操作性等有关。或者他可能只是弄错了。理解规则并能够解释它们是使用规则的重要部分。

答案 3 :(得分:9)

接口是要实现的类的合同,我认为没有理由为什么要从这样的合同中排除属性。此外,属性是.NET固有的。

例如:ICollection<T>同时包含CountIsReadOnly

答案 4 :(得分:2)

之前从未见过这样的事情,但前段时间有人谈到不使用跨平台接口定义中的属性,因为有许多平台不支持属性,但几乎所有都支持方法。

答案 5 :(得分:2)

当你为不同的机器或应用程序域上托管的服务(例如WCF,WebServices,Remoting)定义接口时,我能想到的唯一方法,即为什么属性对接口不好。

由于网络和序列化活动,导致属性意味着它们很快(也就是获取和设置值),这对于服务来说是不正确的。在服务接口中获取或设置值的一种探索方法意味着可能需要一些时间来完成操作。

答案 6 :(得分:1)

我认为没有文件可以支持这个前提。另外,我可以想到BCL中的许多例子恰恰相反。看看几乎所有的集合接口,你会看到属性。

答案 7 :(得分:0)

实际上,属性由两个函数组成:一个用于获取值,另一个用于设置值。尽管属性是C#的一流“特性”,但仍然如此。

为什么接口中不允许使用属性?

答案 8 :(得分:0)

我认为没有理由不将属性作为接口的一部分。您还将如何实现对数据成员的访问?获取方法和设置方法而不是属性。那将是丑陋的,所以1990年代。

答案 9 :(得分:0)

我可以看到属性与方法的唯一缺点是,虽然使用get方法的接口,具有set方法的接口和将两者结合的接口(一种允许最大灵活性的方案)没有问题有协方差和逆变),属性不能很好地结合。我不确定为什么读写属性不仅仅与read属性和write属性相同,但事实并非如此。如果接口支持只读属性和同名的只写属性,则任何通过组合接口访问属性的尝试都将因声明的歧义而失败。

答案 10 :(得分:0)

这是糟糕的设计,因为你污染了实现的变量空间,该变量空间用于存储具有作为类合同一部分的变量的状态。

答案 11 :(得分:0)

IEnumerator是需要属性作为接口成员的场景的完美示例。如果不强制实施者这样做,你将如何存储当前元素?

答案 12 :(得分:0)

我看到这是一个.Net问题;但是,这种想法可能来自Java背景。它使我想起了有效Java中的第22项:仅使用接口来定义类型

此建议并未禁止接口中的所有属性。它专门针对仅包含 属性的接口。

  

当类实现接口时,该接口用作 type ,可用于引用该类的实例。因此,类实现接口应该说明客户端可以使用该类实例执行的操作。为其他目的定义接口是不合适的。

     

一种无法通过此测试的接口是所谓的恒定接口。这样的接口不包含任何方法。它仅由静态最终字段组成...

     

常量接口模式是对接口的不良使用。类在内部使用一些常量是一个实现细节。实现常量接口会导致该实现细节泄漏到类的导出的API中……这表示一种承诺:如果在将来的版本中对该类进行了修改,使其不再需要使用常量,则它仍必须实现该接口以实现以下目的:确保二进制兼容性。如果非最终类实现了常量接口,则其所有子类的名称空间都会受到接口中常量的污染。

当然,Java本身(可能还有C#)包含这些常量接口的示例。这本书也解决了这个问题。

  

Java平台库中有几个常量接口……这些接口应视为异常并且不应被仿真。

我同意以前的回答,我从未见过建议避免避免同时包含属性和方法的接口。