接口命名约定

Fre*_*ool 52 c# interface naming-conventions

这当然是一个主观的事情,但我没有看到任何正面的界面名称前缀为'I'.对我来说,Thing几乎总是比可读性更强IThing.

我的问题是,为什么这个惯例存在呢?当然,它可以更容易地告诉其他类型的接口.但是,这种说法不会延伸到保留现在受到广泛谴责的匈牙利符号吗?

对于那个尴尬的"我",你的论点是什么?或者,更重要的是,微软可能是什么?

Jon*_*jap 76

公约(以及对它们的批评)都有其背后的原因,所以让我们来看看公约背后的一些原因

  • 接口以I为前缀,以区分接口类型与实现 - 例如,如上所述,需要一种简单的方法来区分Thing接口和接口,IThing因此约定用于此目的.

  • 接口以I为前缀,以区别于抽象类 - 当您看到以下代码时,存在歧义:

    public class Apple: Fruit

    如果没有约定,人们就不会知道Apple是从另一个名为继承的继承Fruit,还是它是一个名为的接口的实现Fruit,而IFruit这将使这个显而易见:

    public class Apple: IFruit

    适用最少的原则.

  • 并非所有匈牙利表示法的使用都受到谴责 - 匈牙利表示法的早期使用表示一个前缀,表示对象的类型,然后是变量名称,有时是变量名称前面的下划线.对于某些编程环境(认为Visual Basic 4 - 6)而言,这是有用的,但随着真正的面向对象编程越来越流行,指定类型变得不切实际和冗余.当涉及intellisense时,这成为特别的问题.

    今天,匈牙利符号可以将UI元素与实际数据和类似关联的UI元素(例如,txtObject对于文本框)区lblObject分为与该文本框相关联的标签,而文本框的数据是简单的Object.

    我还必须指出匈牙利表示法的最初用法不是指定数据类型(称为系统匈牙利表示法),而是指定变量名称的语义用法(称为Apps Hungarian Notation).在匈牙利表示法维基百科条目上阅读更多内容.

  • 此外,接口可能会感觉不好,因为它们并没有真正做任何事情.添加我通过让他们感觉凉爽来弥补这一点.使用IPod,IMac,IPhone等也是如此.我让它们看起来更酷. (144认同)
  • 对于大多数接口代表的HAS-A属性,我也是一个有用的例子 - "IHasData","IHasCookie","IHasCheezburger"...... (32认同)
  • +1"让他们感觉凉爽" (8认同)
  • 哈哈!当然,Svish 接口的用途远不止于此。 (2认同)
  • 哈哈为此变成了一个笑话.这一天很好的插曲. (2认同)

Jon*_*n B 24

我这样做的原因很简单:因为这是惯例.我宁愿只关注它而不是让我的所有代码看起来都不同,这使得阅读和学习变得更加困难.

  • 如果我在你的项目中寻找接口并且花了比所需要的时间长十分钟,我会非常生气. (7认同)
  • 这是循环逻辑乔恩."因为这就是它完成的方式"可能是很多人的理由,但我们中的一些人喜欢相信我们的工作. (6认同)
  • @ted - 我的逻辑是你应该遵循这个约定,因为它将提高代码的可读性和可维护性.我不认为这是循环的. (3认同)
  • 如何在_all_你的代码中遵循I-less约定?(我想我会在下一个项目中做到这一点.) (2认同)

Mar*_*ell 23

好吧,一个明显的考虑因素是(非常常见)IFooFoo对(抽象时Foo),但更一般地说,知道某些东西是接口还是类,通常是基础.是的,这部分是多余的,但是IMO与之类似sCustomerName- 在这里,名称本身(customerName)应该足以理解变量.

但是CustomerRepository- 它是一个类,还是一个抽象的接口?

还有:期待; 事实是,对或错,这是人们所期望的.这几乎是理由.

  • @Frederick--我用眼睛读,而不是鼠标......如果我不能通过观察看不到线,那么这条线就自动错了. (10认同)
  • 那么为什么你_care_它是一个接口还是一个类,特别是如果你正在编写客户端代码?不关心:这不是抽象的目的,因此是OOP吗? (5认同)
  • “但是对于 CustomerRepository - 它是一个类,还是抽象接口?” 好吧,至少在 Visual Studio 中,只需将鼠标悬停在它上面即可。这不是编码工具可以比冗余约定更好地帮助我们的情况吗?匈牙利符号不是也被 Visual-Studio-hover 扼杀了吗? (2认同)
  • 好的,如果 Visual Studio 的颜色编码接口与类不同怎么办?这还不足以使区别明显吗?如果是这样,那不是微软应该首先提供的而不是传播阻碍通信的约定吗? (2认同)
  • 我认为我们永远不会在这里达成一致。我没有看到“阻碍沟通的约定”...... (2认同)

0su*_*ain 19

Thing比名字更易读IThing.我来自思想学院,我们应该编程接口而不是特定的实现.所以一般来说,接口应优先于实现.我更喜欢为接口而不是实现提供更易读的名称(即,我的接口名称没有'I'前缀).

  • 让我们把`I`作为实现前缀!;) (6认同)

Gus*_*ori 12

我确定你的问题是微软团队内部关于.NET Framework及其标准的许多冗长讨论的主题.

我认为最有说服力的例子来自源本身.下面,我转录了框架设计指南的摘录,这是我强烈推荐的一本书.

来自Krzysztof Cwalina,CLR项目经理:

接口使用的唯一前缀是"I"(如ICollection),但这是出于历史原因.回想起来,我认为使用常规类型名称会更好.在大多数情况下,开发人员并不关心某些东西是接口而不是抽象类.

来自Brad Abrams,CLR和.NET Framework项目经理:

另一方面,接口上的"I"前缀清楚地表明了COM(和Java)对.NET Framework的影响.COM普及,甚至制度化,接口以"I"开头的符号.虽然我们讨论了与这种历史模式的分歧,但我们决定推进这种模式,因为我们的许多用户已经熟悉了COM.

来自顾问和作者Jeffrey Richter:

就个人而言,我喜欢"我"前缀,我希望我们有更多这样的东西.小的单字符前缀在保持代码简洁和描述性方面有很长的路要走.[...]我使用前缀作为我的私有类型字段,因为我觉得这非常有用.

我的观点是,它在讨论桌上.我看到的一个优点是它有助于避免类和接口之间的名称冲突,因此您的名称可以是描述性的和紧凑的

个人 - 也许是出于习惯 - 我喜欢I前缀,因为它简洁地标记了接口,允许我与实现类型进行一对一的命名对应.当你想提供一个base实现时,这种情况会很明显:IThing是接口,Thing是基类(也许abstract)类型.派生类型可以SomeThing.我喜欢能够使用这种清晰的速记符号.


Otá*_*cio 10

我认为这比在具体类中添加"Impl"后缀更好.这是一个单一的字母,这个惯例很成熟.当然,您可以自由使用任何您想要的命名.


top*_*hef 8

不使用I约定接口没有任何问题 - 只要保持一致并确保它不仅适用于您,而且适用于整个团队(如果有的话).


Aiv*_*var 8

在我看来,这个'我'只是视觉噪音.IDE应以不同方式显示类和接口名称.幸运的是,Java标准库不使用此约定.

  • 以"我认为"开头的回应并不是很好的回应.在很多情况下都有官方指导,如.NET和Microsoft的情况.https://msdn.microsoft.com/en-us/library/8bc1fexb(v=vs.71).aspx (6认同)
  • “ Impl”后缀不只是Java中的视觉干扰吗?@Isaac关于官方指南是正确的。 (3认同)

Gre*_*gor 5

为接口命名应该具有比是否在名称前面添加“I”更深刻的含义。

作为一个界面,“Fruit”和“IFruit”对我来说都没有太多意义。这是因为它看起来更像一个类。类定义事物,而接口应该定义功能。

“I”命名约定确实有助于区分类和接口,以便开发更容易一些。虽然这不是必需的,但它确实有助于避免常见的面向对象编码难题。C# 与 Java 一样,只允许从单个基类继承。但您可以根据需要实现任意多个接口。需要注意的是,如果您从一个类继承并实现一个或多个接口,则必须首先命名基类(即类 Trout:Fish、ISwimmer、IDiver ...)。

我真的很喜欢根据它们提供的功能以及它们的接口类型(即动画或无动画接口)来命名我的接口。

如果您关注接口提供的功能,您可以快速确定接口的名称。它还可以帮助您快速查看您的接口是否定义了不相关的函数。

定义无生命对象(即不能自行行动的事物)的接口...我喜欢以...able结尾来命名它们 IPrintable(例如Document、Invoice) IPlayable(例如Instrument、MediaPlayer) ISavable (如文档、图像) IEdible (如水果、牛肉) IDrivable (如汽车) IFlyable (如飞机)

定义动画对象(即自行行动的事物)的接口...我喜欢将它们命名为...er结尾 ISwimer(例如 Fish、Dog、Duck) IDiver(例如 Fish、Duck) IFlyer(例如 Pilot) IDriver (例如 NascarDriver)

最后,“I”命名约定有助于区分接口和类。但除了开头的“I”之外,添加额外的命名逻辑可能是有意义的。