接口命名约定

时间:2009-03-25 13:58:43

标签: c# interface naming-conventions

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

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

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

21 个答案:

答案 0 :(得分:73)

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

  • 接口以I为前缀,以区分接口类型与实现 - 例如,如上所述,需要一种简单的方法来区分Thing及其接口{{ 1}}所以约定就是为了这个目的。

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

    IThing

    如果没有约定,我不知道public class Apple: Fruit是否从另一个名为Apple的类继承,或者它是实现一个名为Fruit的界面,而Fruit将使这个显而易见:

    IFruit

    适用最少意外的原则。

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

    今天匈牙利语符号可以区分UI元素与实际数据和类似关联的UI元素,例如public class Apple: IFruit用于文本框,txtObject用于与该文本框关联的标签,而数据对于文本框,只需lblObject

    我还必须指出匈牙利表示法的最初用法不是指定数据类型(称为系统匈牙利表示法),而是指定变量名称的语义用法(称为Apps Hungarian Notation)。请在wikipedia entry on Hungarian Notation上了解更多信息。

答案 1 :(得分:23)

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

答案 2 :(得分:22)

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

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

另外:期待;事实是,对或错,这是人们所期望的。那是几乎的理由。

答案 3 :(得分:19)

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

答案 4 :(得分:10)

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

答案 5 :(得分:9)

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

答案 6 :(得分:9)

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

我认为最有说服力的例子来自源本身。下面,我会转录Framework Design Guidelines的摘录,这是我强烈推荐的一本书。

来自Krzysztof Cwalina,CLR项目经理:

  

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

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

  

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

来自顾问和作者Jeffrey Richter:

  

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

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

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

答案 7 :(得分:8)

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

答案 8 :(得分:3)

因为您通常有ITING 一件事。因此,不是让人们为这种反复出现的情况带来他们自己的“惯例”,而是选择了统一的“一刀切”的惯例。与其他人所说的相呼应,事实上的标准就是使用它的理由。

答案 9 :(得分:2)

  

Do prefix interface names with the letter I to indicate that the type is an interface.

指南并没有解释为什么你应该使用I前缀,但事实上这是一个既定的惯例应该是足够的理由。

删除I前缀后,您需要获得什么?

答案 10 :(得分:2)

这只是一个旨在防止名称冲突的惯例。 C#不允许我有一个名为Client的类和接口,即使文件名分别是Client和IClient也是如此。我很习惯使用这个会议;如果我必须提供不同的约定,我建议使用“合同”作为后缀,例如ClientContract。

答案 11 :(得分:2)

我不确切地知道他们为什么选择这种惯例,也许部分地想要用“我”将班级包含在“我是可数的”中。

更符合框架其余部分的命名约定是将类型合并到名称中,例如xxxAttribute和xxxException类,使其成为xxxInterface。这有点冗长,毕竟接口是独立的,而不仅仅是另一堆类。

答案 12 :(得分:1)

看起来Hungarian对我而言。匈牙利语通常被认为是强类型语言的威胁。

由于C#是Microsoft产品,而匈牙利语符号是微软的发明,我可以看到C#可能会受其影响。

答案 13 :(得分:1)

我知道Microsoft指南建议使用“I”将其描述为接口。但这来自IBM命名约定,如果我不记得错了,接口的启动'I'和实现的后续* Impl。

但是,在我看来,Java命名约定是比IBM命名约定更好的选择(不仅在Java中,对于C#以及任何OO编程语言)。接口描述了一个对象在实现接口时能够做什么,并且描述应该是动词形式。 I.e Runnable,Serializable,Invoiceable等。恕我直言,这是界面代表的完美描述。

答案 14 :(得分:1)

将接口与类分开。

此外(这更多的是个人观察,而不是从高处指示),接口描述了一个类的作用。 'I'适合这一点(我确信它是一种语法结构,现在可以很好地鞭打);描述验证类的接口将是“IValidate”。描述匹配行为的是“IMatch”。

答案 15 :(得分:1)

OS GUI使用不同的文件和文件夹图标很受欢迎。如果它们共享相同的图标,但文件夹的前缀为“F”,则可以使用相同的图标。但是,由于人类的图像识别速度比单词识别速度快,我们已经确定了图标。

像IDE这样的计算机程序完全能够使文件的界面显而易见。这将释放出同名的不同抽象级别的名称空间。例如。在“ICare”中,“I”描述了实现,“Care”描述了接口的功能。

我猜测“我”的惯例如此受欢迎,因为我们无法想到更好的东西,但它的存在很重要,因为它指出我们需要知道这种信息。

答案 16 :(得分:1)

命名界面应该具有更深刻的意义,而不仅仅是你是否放置了一个" I"在名字的前面。

没有" Fruit"也不是" IFruit"对我来说,作为一个界面会有很多意义。这是因为它看起来更像是一个类。类定义事物,而接口应定义功能。

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

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

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

定义无生命对象的界面(即无法自行行动的东西)...... 我喜欢用...来命名它们 IPrintable(例如文件,发票) IPlayable(例如Instrument,MediaPlayer) ISavable(如文档,图像) 可食用(如水果,牛肉) 可识别的(如汽车) IFlyable(如飞机)

定义动画对象的界面(即自己动作的东西)...... 我喜欢用......呃命名他们 ISwimer(如鱼,狗,鸭) IDiver(如鱼,鸭) IFlyer(如飞行员) IDriver(如NascarDriver)

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

答案 17 :(得分:0)

事实是每个人都理解它,编写更好的代码的一部分是让它易于阅读和理解。

答案 18 :(得分:0)

我真的不喜欢这个惯例。我知道当你有一个接口和一个具有相同名称的实现时,它会有所帮助,但我发现它很难看。当然,如果它是我工作的惯例,我仍然会遵循它。一致性是惯例,一致性是一件非常好的事情。

我喜欢让界面以尽可能通用的方式描述界面的功能,例如Validator。验证特定事物的特定实现将是ThingValidator,具有Validator共享的一些抽象功能的实现将是AbstractValidator。我会这样做,即使Thing是唯一的......我正在验证的东西...... Validator是通用的。

如果只有一个具体类对接口有意义,我仍然会尝试描述某个特定实现的特定内容,而不是以不同方式命名接口以防止名称冲突。毕竟,我将比实现的名称更频繁地键入接口的名称。

答案 19 :(得分:0)

您可以在自定义界面中添加“Interface”作为后缀,例如“SerializerInterface”。对于抽象类,“Fruit”,例如“FruitAbstract”,或者你可以将它变为“AbstractFruit”,只需要一致。这足够可读,或遵循通常的命名约定。

答案 20 :(得分:0)

我的2美分:

我个人追加后缀“Interface”的原因是因为它比“I”前缀更容易阅读,因为系统中的文件被列为“分组”。例如:

不太好:

Alien.php
Host.php
IAlien.php
IHost.php
IXenomorph.php
Xenomorph.php

更好:

Alien.php
AlienInterface.php
Host.php
HostInterface.php
Xenomorph.php
XenomorphInterface.php

但这只是个人品味。我认为只要在整个项目中使用一致的命名约定,就没有什么可以反对使用您自己的命名约定。