为什么用“I”前缀C#接口名称

时间:2021-06-29 10:20:53

What is the rationale behind this naming convention?

这个命名惯例背后的理由是什么?

I don't see any benefit. The extra prefix just pollutes the API.

我没有看到任何好处。额外的前缀只会污染API。

My thinking is inline with Konrad's response to this related question; the chosen answer of which is mostly what I am asking for here.

我的想法与康拉德对这个相关问题的回答是一致的;所选择的答案主要是我在这里要求的。

18 个解决方案

#1


Its the complete opposite, the naming convention clearly identifies an interface.

完全相反,命名约定清楚地标识了一个接口。

For example if you have:

例如,如果你有:

public class Dog : IPet, IMammal
{
    ....

Just from reading it, I can safely assume that IPet and IMammal are probably interfaces.

仅仅是阅读它,我可以放心地假设IPet和IMammal可能是接口。

The .NET CLR allows for single class inheritance. So, if I have a base class..I can only inherit one class from it. Lets change the IPet interface to a base class..our example now becomes

.NET CLR允许单类继承。所以,如果我有一个基类..我只能从它继承一个类。让我们将IPet接口更改为基类。现在我们的示例变为

public class Dog : Pet, IMammal
{
    ....

I am inheriting from the Pet class and implementing the IMammal interface.

我继承Pet类并实现IMammal接口。

If we did it what you are suggesting and removed the letter "I" we have this:

如果我们按照你的建议做了,并删除了字母“我”我们有这个:

public class Dog : Pet, Mammal
{
    ....

Which one is the class I am inheriting from? Which is the interface I am implementing? It gets confusing right? (FYI..you are supposed to put the base class always first, so you could argue that point...but if you are arguing to remove the letter I from prefixing interface names I doubt you follow that practice as well)

哪一个是我继承的班级?我正在实现哪个界面?这让人感到困惑吧? (仅供参考。你应该把基类放在第一位,所以你可以争论这一点......但是如果你想从界面名称前面删除字母I我怀疑你也遵循这种做法)

As you can see that naming convention easily tells me a lot about my object without me having to investigate further. I can easily see what I am inheriting vs what I am implementing.

正如您所看到的那样,命名约定很容易让我对我的对象有很多了解,而我无需进一步调查。我可以很容易地看到我继承的内容与我正在实施的内容。

#2


I also like it cause I can read it as "I verb-behavior" as in "ICanSave" or "IDoDoubleEntry" etc...

我也喜欢它,因为我可以把它读作“我动词行为”,如“ICanSave”或“IDoDoubleEntry”等...

#3


I think that the IInterface naming convention is silly. It's an example of Hungarian notation, and I subscribe to the school of thought that despises Hungarian notation. If you have an interface with only one implementation that has the same name, consider the possibility that this is a code smell.

我认为IInterface命名约定很愚蠢。这是匈牙利符号的一个例子,我赞同鄙视匈牙利符号的思想学派。如果您的接口只有一个具有相同名称的实现,请考虑这可能是代码异味。

However, I still use it, because in this case IInterface is recommended by Microsoft, and "standard is better than better".

但是,我仍然使用它,因为在这种情况下,Microsoft推荐使用IInterface,并且“标准优于更好”。

#4


Why isn't this a function of syntactical highlighting instead of Hungarian notation? Why doesn't the IDE just italicize identifiers that refer to interfaces if it's so important to distinguish between classes and interfaces. I hate putting "" or "m" before fields, "C" before classes, etc. Even worse, it encourages programmers write really bad APIs such as:

为什么这不是语法高亮而不是匈牙利符号的功能?如果区分类和接口如此重要,那么为什么IDE不会仅仅使用引用接口的标识符。我讨厌在字段前加“”或“m”,在课前加“C”等。更糟糕的是,它鼓励程序员编写非常糟糕的API,例如:

public class List : IList

instead of a more reasonable:

而不是更合理:

public class LinkedList : List
public class ArrayList : List
public class HashList : List

Even the .NET common class authors fell into this trap. A class name should NEVER be the name of the interface with just the "I" removed. The class name should always tell the user how the class differs from other possible implementations of the interface(s). I vote for dropping the stupid "I" for that reason alone.

即使是.NET普通类作者也陷入了这个陷阱。类名永远不应该是只删除了“I”的接口的名称。类名应始终告诉用户类与接口的其他可能实现的不同之处。因为这个原因我投票放弃了愚蠢的“我”。

Also, when I use intellisense, I want to group things by functional area, not whether it's a class or interface. I never think, "I need an interface, not a class." I always think, "I need something that does X".

此外,当我使用intellisense时,我想按功能区域分组,而不是它是一个类还是接口。我从不认为,“我需要一个界面,而不是一个类。”我一直认为,“我需要做X的东西”。

#5


Actually I find it useful to avoid naming *es, I might for example create a concrete class called Fred that implements IFred

实际上我发现避免命名冲突很有用,例如我可以创建一个名为Fred的具体类来实现IFred

#6


If you consider the two "best-practice-aphorisms"

如果你考虑两个“最佳实践 - 格言”

clarity is king

清晰度是王道

and

noise is bad

噪音很糟糕

there is a conflict between these. The question is: when does clarity become noise?

这些之间存在冲突。问题是:什么时候清晰度会变成噪音?

For me it more noisy (but equally clear) to write Person person = new PersonImpl() than IPerson person = new Person().

对我来说,编写Person person = new PersonImpl()比IPerson person = new Person()更嘈杂(但同样清晰)。

#7


I always thought it was fun to use verbs for behavioral interfaces. This is a departure from the class naming convention of using nouns, but it allows the class to "speak" to its behavior.

我一直认为将动词用于行为界面很有趣。这与使用名词的类命名约定不同,但它允许类“说出”它的行为。

class Dog: IBark

This does not work well for structural interfaces like WCF interfaces, but we don't need to have fun all the time.

这对于像WCF接口这样的结构接口不适用,但我们不需要一直玩得开心。

to answer your question, think of the I as "implements" So...

回答你的问题,把我想成“工具”所以......

class DogDataService : Dog, IDataService

this service class inherits from Dog and implements IDataService

此服务类继承自Dog并实现IDataService

I'm still not really answering your question, but the I is useful because you get naming collisions between namespace, class and interface.

我仍然没有真正回答你的问题,但我很有用,因为你得到命名空间,类和接口之间的命名冲突。

namespace DataService
interface DataService
class DataService: DataService

so we end up with

所以我们最终得到了

namespace DataServices
interface IDataService
class DataService : IDataService

I think in reality, it's a sanity convention.

我认为实际上,这是一个理智的惯例。

#8


It's either that or add "Impl" to the implementation of the interface (argh). I don't have a problem with the "I", it is the simplest and most straightforward naming for an interface.

它是或者在接口的实现中添加“Impl”(argh)。我对“I”没有问题,它是界面最简单,最直接的命名。

#9


The "I" convention seems to be an old convention that wouldn't be relevant today. Current code editor provides lots of insight about the type you are using, so arguing that It's easier to identify the interface is like asking for a namespace to be prefixed by a "N" because you want to be sure that you will not confound it with a concrete class (prefix with a "C"?).

“I”公约似乎是一个旧的惯例,今天不相关。当前的代码编辑器提供了许多关于您正在使用的类型的见解,因此认为识别接口更容易就像要求命名空间以“N”为前缀,因为您要确保不会将其与具体类(带有“C”的前缀?)。

A convention doesn't mean that It's a good convention. Sometimes, It's just because people get to use it...

约定并不意味着它是一个很好的约定。有时,这只是因为人们开始使用它......

Take for example the C# documentation generator: It doesn't care about it... if your interface is not prefixed with a "I" you will still see your interface in the interface part of your documentation. Do you really think that having a prefix "I" for all your interfaces inside the interface section of your documentation is a relevant information and help you to better identify interfaces?

以C#文档生成器为例:它并不关心它......如果你的界面没有以“我”作为前缀,你仍然会在文档的界面部分看到你的界面。您是否真的认为在文档的界面部分中为所有接口添加前缀“I”是相关信息并帮助您更好地识别接口?

#10


It makes it easily identifiable as an interface.

它使其易于识别为界面。

#11


The need to differentiate between an interface and a class actually indicates a design flaw. In a well designed application, it will always be clear. A subclass should always be a specialization and classes can only be specialized in one subject, never more.

区分接口和类的需要实际上表明了设计缺陷。在设计良好的应用程序中,它总是很清楚。子类应该始终是一个专门化,类只能专注于一个主题,而不是更多。

A class should have a single reason for existence. It should never be required to put secondary roles in a base class. E.g.:

一个班级应该有一个存在的理由。永远不需要将辅助角色放在基类中。例如。:

public class XmlConfigurationFile : ConfigurationFile, IDisposable
{
}

public class YamlConfigurationFile : ConfigurationFile, IDisposable
{
}

The first one is a configuration file that is specialized in Xml, the second one is specialized in Yaml. These are also disposable, but that doesn't matter as much. You didn't create these two classes because of a different disposing processes.

第一个是专门用于Xml的配置文件,第二个是专门用于Yaml的配置文件。这些也是一次性的,但这并不重要。由于处理过程不同,您没有创建这两个类。

Constrast this with:

与此相反:

public class XmlConfigurationFile : IDisposable, ConfigurationFile
{
}

This will tell you that the main purpose a XmlConfigurationFile has, is that it is disposable. That you can use it as a way to represent configuration files is nice, but is secondary.

这将告诉你XmlConfigurationFile的主要目的是它是一次性的。您可以使用它作为表示配置文件的方式很好,但是次要的。

The problem starts when you create classes that have multiple reasons for existence:

当您创建具有多个存在理由的类时,问题就开始了:

public class MyConfigurationFile : XmlConfigurationFile, YamlConfigurationFile
{
}

Even if XmlConfigurationFile and YamlConfigurationFile would have been interfaces, it still indicates bad design. How can your configuration file be Xml and Yaml at the same time?

即使XmlConfigurationFile和YamlConfigurationFile是接口,它仍然表明设计不好。你的配置文件如何同时是Xml和Yaml?

If you read through the examples given (here and elsewhere), people always struggle to find a good example of when the I-prefix matters. One of the answers here is:

如果你仔细阅读给出的例子(这里和其他地方),人们总是很难找到I-prefix很重要的好例子。其中一个答案是:

public class Dog : Pet, Mammal
{
}

This is how this class will look like in an application about pets. A dog's main purpose is being a specialized pet, that can do pet-related things, not that it is a mammal.

这就是这个类在关于宠物的应用程序中的样子。狗的主要目的是成为一种专门的宠物,它可以做与宠物有关的事情,而不是它是一种哺乳动物。

public class Dog : Mammal, Pet
{
}

This is how the same class will look like in an application about animal classifications. It is nice to know a dog is a pet, but it's main purpose is being a specialized mammal, that can do mammal-related things.

这是关于动物分类的应用程序中同一类的外观。很高兴知道狗是宠物,但它的主要目的是成为一种专门的哺乳动物,可以做与哺乳动物有关的事情。

I think your classes should tell you the correct story about the architecture and domain of your application. Requiring an interface to be prefixed with an 'I' is a technical requirement and doesn't help you to tell your application's story better.

我认为您的课程应该告诉您有关应用程序的体系结构和域的正确故事。要求界面以“I”为前缀是技术要求,并不能帮助您更好地讲述应用程序的故事。

Once you start writing small, dedicated, single-purpose classes, the need for knowing if it implements or extends will automatically vanish.

一旦开始编写小型,专用的单一用途类,了解它是否实现或扩展的需求将自动消失。

#12


Naming conventions offer the benefit of telling you something about the object before you use it. Naming conventions have been widely used for many years, going all the way back to fortran's insistence that integer values were restricted (if I remember correctly) to variable names like "i" and "j".

命名约定提供了在使用之前告诉您有关该对象的一些好处。命名约定已被广泛使用多年,一直回到fortran的坚持,即整数值被限制(如果我没记错的话)变量名称如“i”和“j”。

Hungariation notation took naming conventions to a whole new ugly level tha described the variable type, whether or not it was a pointer, etc. Many of us who were exposed to lots of code with Hungarian notation developed nervous twitches and verbal stutters.

Hungariation表示法将命名约定用于描述变量类型的全新丑陋程度,无论它是否是指针等等。我们中的许多人用匈牙利符号暴露了大量代码,发生了紧张的抽搐和口头口吃。

Prefixing interface names with I is a relatively low-impact, harmless way of identifying that object.

使用I前缀接口名称是一种识别该对象的影响相对较小,无害的方法。

#13


TL;DR - Extracting interface IFoo from class Foo is common in SOLID decoupling, especially for Unit Testing purposes

TL; DR - 从类Foo中提取接口IFoo在SOLID解耦中很常见,特别是对于单元测试目的

To me the dual convention of class Foo implementing interface IFoo (especially if both are in the same assembly) conveys a specific intention that:

对我来说,类Foo实现接口IFoo的双重约定(特别是如果两者都在同一个程序集中)传达了一个特定的意图:

  • Coupling on a dependency to a Foo should always be indirect, through the corresponding IFoo interface (and likely to be injected via an IoC container)
  • 依赖于Foo的依赖应该始终是间接的,通过相应的IFoo接口(并且可能通过IoC容器注入)

  • The initial design of IFoo is a proprietary, non-reusable interface specifically to allow classes dependent on Foo to mock out this dependency during unit testing.
  • IFoo的初始设计是专有的,不可重用的接口,专门用于允许依赖于Foo的类在单元测试期间模拟这种依赖性。

  • Beyond the above, a reader doesn't need to infer any additional intelligence in the design of the IFoo interface
  • 除此之外,读者不需要在IFoo接口的设计中推断任何额外的智能

  • Conversely, if multiple concrete implementation classes of IFoo are required at a later point, that proper interface segregation design will need to be retrofitted into the hierarchy.
  • 相反,如果稍后需要IFoo的多个具体实现类,则需要将适当的接口隔离设计改进到层次结构中。

Rationale

In order to be able to Mock or Stub out a class, a widely accepted best practice in Unit Testing is to decouple dependencies between classes only via interfaces. This interface decoupling will also be done to classes which would otherwise never had a design requirement for polymorphicism (i.e. only one such implementation would have existed, were it not for the need for unit testing).

为了能够Mock或Stub一个类,单元测试中广泛接受的最佳实践是仅通过接口来解耦类之间的依赖关系。这种接口解耦也将用于那些本来就没有多态性设计要求的类(即,只有一个这样的实现存在,如果它不是单元测试的需要)。

As a consequence, the refactoring and reuse of these interfaces (e.g. the Interface Segregation Principal of SOLID) isn't frequently applied to such 'mockable' interfaces - there is often a 1:1 correlation between the public methods, properties and events of a 'mockable' class (Foo) and its decoupled interface IFoo (similar to the COM-era automatic interfaces in VB).

因此,这些接口的重构和重用(例如SOLID的接口隔离主体)并不经常应用于这种“可模拟”接口 - 公共方法,属性和事件之间通常存在1:1的相关性。 'mockable'类(Foo)及其解耦接口IFoo(类似于VB中的COM时代自动接口)。

Tools such as VS and Resharper can make extracting such public symbols from a class into a separate interface trivial, as an afterthought.

诸如VS和Resharper之类的工具可以将这样的公共符号从类中提取到一个单独的接口中,作为事后的想法。

Further, if we consider that Mocking frameworks like Moq allow definition of implementations of the interface on-the-fly, we need not waste effort naming the concrete test double implementation class.

此外,如果我们认为像Moq这样的Mocking框架允许动态定义接口的实现,我们不需要浪费精力来命名具体的测试双实现类。

#14


It is just a naming convention so everybody would know if it is an interface or something else it is not mandatory nor by the compiler nor by the IDE but All the interfaces i saw in my entire life starts with the letter I

它只是一个命名约定,所以每个人都知道它是一个接口还是别的东西它不是强制性的,也不是编译器或IDE,但我一生中看到的所有接口都以字母I开头

#15


I seems to traditional convention from Hungarian Notation. Interface Naming Guidelines says "Prefix interface names with the letter I, to indicate that the type is an interface." Framework Design Guidelines also says "DO prefix interface names with the letter I, to indicate that the type is an interface."

我似乎是匈牙利表示法的传统惯例。接口命名准则说“使用字母I前缀接口名称,以指示该类型是接口。”框架设计指南还说“DO前缀接口名称带字母I,表示该类型是接口。”

It is just a coding convention, So it's to hard to determine good or bad. Important things is consistency.

这只是一个编码惯例,所以很难确定好坏。重要的是一致性。

#16


Firstly I believe prefixing with I then description is wrong because it means implementations can have a shorter name. IList (intf) -> List. This is an anti-pattern as we all know we should be using intf and probably only concrete types when creating. Don't flame me this is a generalization but the premise is intf only impl rarely. The implementation name should describe how it's implementing the intf or what it's doing. Think intf List, LinkedList which implements List using a linked list. Who cares if it's longer as we should be using List most of the time. If we have a class implementing many intf we probably should not include all the intf as the shadows the real purpose of the class. IN the case something removed without the intf makes sense. Eg ppl call me by name not Person, Sibling, developer etc using my name is the best most descriptive name. I suppose if a class is impl a simple intf then call it Default Intf which makes it on ious this is the default implementation of Intf. Names of classes sHould in the end be human readable and almost a short phrase describing their purpose. Prefix codes etc are not great as we communicate with words not codes. Computers do t cAre what classes are called so why remains is that we name things so the names help us and our colleagues.

首先,我认为前缀为I然后描述是错误的,因为它意味着实现可以有一个较短的名称。 IList(intf) - >列表。这是一个反模式,因为我们都知道我们应该使用intf,并且在创建时可能只是具体的类型。不要焚烧我这是一个概括,但前提是intf很少只是impl。实现名称应该描述它是如何实现intf或它正在做什么的。想一想使用链表实现List的List,LinkedList。谁在乎它是否更长,因为我们应该在大多数时间使用List。如果我们有一个实现了许多intf的类,我们可能不应该将所有intf作为阴影包含在类的真正目的中。在没有intf的情况下移除的东西是有道理的。例如,ppl通过名字给我打电话,而不是使用我的名字的人,兄弟,开发人员等是最具描述性的名称。我想如果一个类是impl一个简单的intf然后调用它的默认Intf,这使它成为ious这是Intf的默认实现。类的名称最终应该是人类可读的,几乎是描述其目的的短语。前缀代码等不是很好,因为我们与单词进行通信而不是代码。计算机不管怎样调用什么类,所以我们为什么命名,所以这些名称可以帮助我们和我们的同事。

#17


Most likely its to make it easily identifiable in intellisense, since all the interfaces will clump together. Similar to how I prefix all my UI controls with btn, tb, lb. When intellisense kicks in everything is clumped together in one easy group.

最有可能的是它可以在intellisense中轻松识别,因为所有接口都会聚集在一起。类似于我使用btn,tb,lb为我的所有UI控件添加前缀。当intellisense踢出所有内容时,在一个简单的组中聚集在一起。

#18


With all of the arguments about naming conventions and giving proper names to variables and methods that actually describe what they do...why not just name your interfaces (e.g. PetInterface, PlayerInterface, etc.) and do away with the prefix "I" all together. So what you have to type an additional 9 letters, at least the "I" is removed and we know it is not a class, because it says "Interface".

有了关于命名约定的所有参数,并给实际描述它们所做的变量和方法的专有名称......为什么不只是命名你的接口(例如PetInterface,PlayerInterface等)并取消前缀“I”all一起。所以你必须输入另外9个字母,至少删除“I”,我们知道它不是一个类,因为它说“接口”。

#1


Its the complete opposite, the naming convention clearly identifies an interface.

完全相反,命名约定清楚地标识了一个接口。

For example if you have:

例如,如果你有:

public class Dog : IPet, IMammal
{
    ....

Just from reading it, I can safely assume that IPet and IMammal are probably interfaces.

仅仅是阅读它,我可以放心地假设IPet和IMammal可能是接口。

The .NET CLR allows for single class inheritance. So, if I have a base class..I can only inherit one class from it. Lets change the IPet interface to a base class..our example now becomes

.NET CLR允许单类继承。所以,如果我有一个基类..我只能从它继承一个类。让我们将IPet接口更改为基类。现在我们的示例变为

public class Dog : Pet, IMammal
{
    ....

I am inheriting from the Pet class and implementing the IMammal interface.

我继承Pet类并实现IMammal接口。

If we did it what you are suggesting and removed the letter "I" we have this:

如果我们按照你的建议做了,并删除了字母“我”我们有这个:

public class Dog : Pet, Mammal
{
    ....

Which one is the class I am inheriting from? Which is the interface I am implementing? It gets confusing right? (FYI..you are supposed to put the base class always first, so you could argue that point...but if you are arguing to remove the letter I from prefixing interface names I doubt you follow that practice as well)

哪一个是我继承的班级?我正在实现哪个界面?这让人感到困惑吧? (仅供参考。你应该把基类放在第一位,所以你可以争论这一点......但是如果你想从界面名称前面删除字母I我怀疑你也遵循这种做法)

As you can see that naming convention easily tells me a lot about my object without me having to investigate further. I can easily see what I am inheriting vs what I am implementing.

正如您所看到的那样,命名约定很容易让我对我的对象有很多了解,而我无需进一步调查。我可以很容易地看到我继承的内容与我正在实施的内容。

#2


I also like it cause I can read it as "I verb-behavior" as in "ICanSave" or "IDoDoubleEntry" etc...

我也喜欢它,因为我可以把它读作“我动词行为”,如“ICanSave”或“IDoDoubleEntry”等...

#3


I think that the IInterface naming convention is silly. It's an example of Hungarian notation, and I subscribe to the school of thought that despises Hungarian notation. If you have an interface with only one implementation that has the same name, consider the possibility that this is a code smell.

我认为IInterface命名约定很愚蠢。这是匈牙利符号的一个例子,我赞同鄙视匈牙利符号的思想学派。如果您的接口只有一个具有相同名称的实现,请考虑这可能是代码异味。

However, I still use it, because in this case IInterface is recommended by Microsoft, and "standard is better than better".

但是,我仍然使用它,因为在这种情况下,Microsoft推荐使用IInterface,并且“标准优于更好”。

#4


Why isn't this a function of syntactical highlighting instead of Hungarian notation? Why doesn't the IDE just italicize identifiers that refer to interfaces if it's so important to distinguish between classes and interfaces. I hate putting "" or "m" before fields, "C" before classes, etc. Even worse, it encourages programmers write really bad APIs such as:

为什么这不是语法高亮而不是匈牙利符号的功能?如果区分类和接口如此重要,那么为什么IDE不会仅仅使用引用接口的标识符。我讨厌在字段前加“”或“m”,在课前加“C”等。更糟糕的是,它鼓励程序员编写非常糟糕的API,例如:

public class List : IList

instead of a more reasonable:

而不是更合理:

public class LinkedList : List
public class ArrayList : List
public class HashList : List

Even the .NET common class authors fell into this trap. A class name should NEVER be the name of the interface with just the "I" removed. The class name should always tell the user how the class differs from other possible implementations of the interface(s). I vote for dropping the stupid "I" for that reason alone.

即使是.NET普通类作者也陷入了这个陷阱。类名永远不应该是只删除了“I”的接口的名称。类名应始终告诉用户类与接口的其他可能实现的不同之处。因为这个原因我投票放弃了愚蠢的“我”。

Also, when I use intellisense, I want to group things by functional area, not whether it's a class or interface. I never think, "I need an interface, not a class." I always think, "I need something that does X".

此外,当我使用intellisense时,我想按功能区域分组,而不是它是一个类还是接口。我从不认为,“我需要一个界面,而不是一个类。”我一直认为,“我需要做X的东西”。

#5


Actually I find it useful to avoid naming *es, I might for example create a concrete class called Fred that implements IFred

实际上我发现避免命名冲突很有用,例如我可以创建一个名为Fred的具体类来实现IFred

#6


If you consider the two "best-practice-aphorisms"

如果你考虑两个“最佳实践 - 格言”

clarity is king

清晰度是王道

and

noise is bad

噪音很糟糕

there is a conflict between these. The question is: when does clarity become noise?

这些之间存在冲突。问题是:什么时候清晰度会变成噪音?

For me it more noisy (but equally clear) to write Person person = new PersonImpl() than IPerson person = new Person().

对我来说,编写Person person = new PersonImpl()比IPerson person = new Person()更嘈杂(但同样清晰)。

#7


I always thought it was fun to use verbs for behavioral interfaces. This is a departure from the class naming convention of using nouns, but it allows the class to "speak" to its behavior.

我一直认为将动词用于行为界面很有趣。这与使用名词的类命名约定不同,但它允许类“说出”它的行为。

class Dog: IBark

This does not work well for structural interfaces like WCF interfaces, but we don't need to have fun all the time.

这对于像WCF接口这样的结构接口不适用,但我们不需要一直玩得开心。

to answer your question, think of the I as "implements" So...

回答你的问题,把我想成“工具”所以......

class DogDataService : Dog, IDataService

this service class inherits from Dog and implements IDataService

此服务类继承自Dog并实现IDataService

I'm still not really answering your question, but the I is useful because you get naming collisions between namespace, class and interface.

我仍然没有真正回答你的问题,但我很有用,因为你得到命名空间,类和接口之间的命名冲突。

namespace DataService
interface DataService
class DataService: DataService

so we end up with

所以我们最终得到了

namespace DataServices
interface IDataService
class DataService : IDataService

I think in reality, it's a sanity convention.

我认为实际上,这是一个理智的惯例。

#8


It's either that or add "Impl" to the implementation of the interface (argh). I don't have a problem with the "I", it is the simplest and most straightforward naming for an interface.

它是或者在接口的实现中添加“Impl”(argh)。我对“I”没有问题,它是界面最简单,最直接的命名。

#9


The "I" convention seems to be an old convention that wouldn't be relevant today. Current code editor provides lots of insight about the type you are using, so arguing that It's easier to identify the interface is like asking for a namespace to be prefixed by a "N" because you want to be sure that you will not confound it with a concrete class (prefix with a "C"?).

“I”公约似乎是一个旧的惯例,今天不相关。当前的代码编辑器提供了许多关于您正在使用的类型的见解,因此认为识别接口更容易就像要求命名空间以“N”为前缀,因为您要确保不会将其与具体类(带有“C”的前缀?)。

A convention doesn't mean that It's a good convention. Sometimes, It's just because people get to use it...

约定并不意味着它是一个很好的约定。有时,这只是因为人们开始使用它......

Take for example the C# documentation generator: It doesn't care about it... if your interface is not prefixed with a "I" you will still see your interface in the interface part of your documentation. Do you really think that having a prefix "I" for all your interfaces inside the interface section of your documentation is a relevant information and help you to better identify interfaces?

以C#文档生成器为例:它并不关心它......如果你的界面没有以“我”作为前缀,你仍然会在文档的界面部分看到你的界面。您是否真的认为在文档的界面部分中为所有接口添加前缀“I”是相关信息并帮助您更好地识别接口?

#10


It makes it easily identifiable as an interface.

它使其易于识别为界面。

#11


The need to differentiate between an interface and a class actually indicates a design flaw. In a well designed application, it will always be clear. A subclass should always be a specialization and classes can only be specialized in one subject, never more.

区分接口和类的需要实际上表明了设计缺陷。在设计良好的应用程序中,它总是很清楚。子类应该始终是一个专门化,类只能专注于一个主题,而不是更多。

A class should have a single reason for existence. It should never be required to put secondary roles in a base class. E.g.:

一个班级应该有一个存在的理由。永远不需要将辅助角色放在基类中。例如。:

public class XmlConfigurationFile : ConfigurationFile, IDisposable
{
}

public class YamlConfigurationFile : ConfigurationFile, IDisposable
{
}

The first one is a configuration file that is specialized in Xml, the second one is specialized in Yaml. These are also disposable, but that doesn't matter as much. You didn't create these two classes because of a different disposing processes.

第一个是专门用于Xml的配置文件,第二个是专门用于Yaml的配置文件。这些也是一次性的,但这并不重要。由于处理过程不同,您没有创建这两个类。

Constrast this with:

与此相反:

public class XmlConfigurationFile : IDisposable, ConfigurationFile
{
}

This will tell you that the main purpose a XmlConfigurationFile has, is that it is disposable. That you can use it as a way to represent configuration files is nice, but is secondary.

这将告诉你XmlConfigurationFile的主要目的是它是一次性的。您可以使用它作为表示配置文件的方式很好,但是次要的。

The problem starts when you create classes that have multiple reasons for existence:

当您创建具有多个存在理由的类时,问题就开始了:

public class MyConfigurationFile : XmlConfigurationFile, YamlConfigurationFile
{
}

Even if XmlConfigurationFile and YamlConfigurationFile would have been interfaces, it still indicates bad design. How can your configuration file be Xml and Yaml at the same time?

即使XmlConfigurationFile和YamlConfigurationFile是接口,它仍然表明设计不好。你的配置文件如何同时是Xml和Yaml?

If you read through the examples given (here and elsewhere), people always struggle to find a good example of when the I-prefix matters. One of the answers here is:

如果你仔细阅读给出的例子(这里和其他地方),人们总是很难找到I-prefix很重要的好例子。其中一个答案是:

public class Dog : Pet, Mammal
{
}

This is how this class will look like in an application about pets. A dog's main purpose is being a specialized pet, that can do pet-related things, not that it is a mammal.

这就是这个类在关于宠物的应用程序中的样子。狗的主要目的是成为一种专门的宠物,它可以做与宠物有关的事情,而不是它是一种哺乳动物。

public class Dog : Mammal, Pet
{
}

This is how the same class will look like in an application about animal classifications. It is nice to know a dog is a pet, but it's main purpose is being a specialized mammal, that can do mammal-related things.

这是关于动物分类的应用程序中同一类的外观。很高兴知道狗是宠物,但它的主要目的是成为一种专门的哺乳动物,可以做与哺乳动物有关的事情。

I think your classes should tell you the correct story about the architecture and domain of your application. Requiring an interface to be prefixed with an 'I' is a technical requirement and doesn't help you to tell your application's story better.

我认为您的课程应该告诉您有关应用程序的体系结构和域的正确故事。要求界面以“I”为前缀是技术要求,并不能帮助您更好地讲述应用程序的故事。

Once you start writing small, dedicated, single-purpose classes, the need for knowing if it implements or extends will automatically vanish.

一旦开始编写小型,专用的单一用途类,了解它是否实现或扩展的需求将自动消失。

#12


Naming conventions offer the benefit of telling you something about the object before you use it. Naming conventions have been widely used for many years, going all the way back to fortran's insistence that integer values were restricted (if I remember correctly) to variable names like "i" and "j".

命名约定提供了在使用之前告诉您有关该对象的一些好处。命名约定已被广泛使用多年,一直回到fortran的坚持,即整数值被限制(如果我没记错的话)变量名称如“i”和“j”。

Hungariation notation took naming conventions to a whole new ugly level tha described the variable type, whether or not it was a pointer, etc. Many of us who were exposed to lots of code with Hungarian notation developed nervous twitches and verbal stutters.

Hungariation表示法将命名约定用于描述变量类型的全新丑陋程度,无论它是否是指针等等。我们中的许多人用匈牙利符号暴露了大量代码,发生了紧张的抽搐和口头口吃。

Prefixing interface names with I is a relatively low-impact, harmless way of identifying that object.

使用I前缀接口名称是一种识别该对象的影响相对较小,无害的方法。

#13


TL;DR - Extracting interface IFoo from class Foo is common in SOLID decoupling, especially for Unit Testing purposes

TL; DR - 从类Foo中提取接口IFoo在SOLID解耦中很常见,特别是对于单元测试目的

To me the dual convention of class Foo implementing interface IFoo (especially if both are in the same assembly) conveys a specific intention that:

对我来说,类Foo实现接口IFoo的双重约定(特别是如果两者都在同一个程序集中)传达了一个特定的意图:

  • Coupling on a dependency to a Foo should always be indirect, through the corresponding IFoo interface (and likely to be injected via an IoC container)
  • 依赖于Foo的依赖应该始终是间接的,通过相应的IFoo接口(并且可能通过IoC容器注入)

  • The initial design of IFoo is a proprietary, non-reusable interface specifically to allow classes dependent on Foo to mock out this dependency during unit testing.
  • IFoo的初始设计是专有的,不可重用的接口,专门用于允许依赖于Foo的类在单元测试期间模拟这种依赖性。

  • Beyond the above, a reader doesn't need to infer any additional intelligence in the design of the IFoo interface
  • 除此之外,读者不需要在IFoo接口的设计中推断任何额外的智能

  • Conversely, if multiple concrete implementation classes of IFoo are required at a later point, that proper interface segregation design will need to be retrofitted into the hierarchy.
  • 相反,如果稍后需要IFoo的多个具体实现类,则需要将适当的接口隔离设计改进到层次结构中。

Rationale

In order to be able to Mock or Stub out a class, a widely accepted best practice in Unit Testing is to decouple dependencies between classes only via interfaces. This interface decoupling will also be done to classes which would otherwise never had a design requirement for polymorphicism (i.e. only one such implementation would have existed, were it not for the need for unit testing).

为了能够Mock或Stub一个类,单元测试中广泛接受的最佳实践是仅通过接口来解耦类之间的依赖关系。这种接口解耦也将用于那些本来就没有多态性设计要求的类(即,只有一个这样的实现存在,如果它不是单元测试的需要)。

As a consequence, the refactoring and reuse of these interfaces (e.g. the Interface Segregation Principal of SOLID) isn't frequently applied to such 'mockable' interfaces - there is often a 1:1 correlation between the public methods, properties and events of a 'mockable' class (Foo) and its decoupled interface IFoo (similar to the COM-era automatic interfaces in VB).

因此,这些接口的重构和重用(例如SOLID的接口隔离主体)并不经常应用于这种“可模拟”接口 - 公共方法,属性和事件之间通常存在1:1的相关性。 'mockable'类(Foo)及其解耦接口IFoo(类似于VB中的COM时代自动接口)。

Tools such as VS and Resharper can make extracting such public symbols from a class into a separate interface trivial, as an afterthought.

诸如VS和Resharper之类的工具可以将这样的公共符号从类中提取到一个单独的接口中,作为事后的想法。

Further, if we consider that Mocking frameworks like Moq allow definition of implementations of the interface on-the-fly, we need not waste effort naming the concrete test double implementation class.

此外,如果我们认为像Moq这样的Mocking框架允许动态定义接口的实现,我们不需要浪费精力来命名具体的测试双实现类。

#14


It is just a naming convention so everybody would know if it is an interface or something else it is not mandatory nor by the compiler nor by the IDE but All the interfaces i saw in my entire life starts with the letter I

它只是一个命名约定,所以每个人都知道它是一个接口还是别的东西它不是强制性的,也不是编译器或IDE,但我一生中看到的所有接口都以字母I开头

#15


I seems to traditional convention from Hungarian Notation. Interface Naming Guidelines says "Prefix interface names with the letter I, to indicate that the type is an interface." Framework Design Guidelines also says "DO prefix interface names with the letter I, to indicate that the type is an interface."

我似乎是匈牙利表示法的传统惯例。接口命名准则说“使用字母I前缀接口名称,以指示该类型是接口。”框架设计指南还说“DO前缀接口名称带字母I,表示该类型是接口。”

It is just a coding convention, So it's to hard to determine good or bad. Important things is consistency.

这只是一个编码惯例,所以很难确定好坏。重要的是一致性。

#16


Firstly I believe prefixing with I then description is wrong because it means implementations can have a shorter name. IList (intf) -> List. This is an anti-pattern as we all know we should be using intf and probably only concrete types when creating. Don't flame me this is a generalization but the premise is intf only impl rarely. The implementation name should describe how it's implementing the intf or what it's doing. Think intf List, LinkedList which implements List using a linked list. Who cares if it's longer as we should be using List most of the time. If we have a class implementing many intf we probably should not include all the intf as the shadows the real purpose of the class. IN the case something removed without the intf makes sense. Eg ppl call me by name not Person, Sibling, developer etc using my name is the best most descriptive name. I suppose if a class is impl a simple intf then call it Default Intf which makes it on ious this is the default implementation of Intf. Names of classes sHould in the end be human readable and almost a short phrase describing their purpose. Prefix codes etc are not great as we communicate with words not codes. Computers do t cAre what classes are called so why remains is that we name things so the names help us and our colleagues.

首先,我认为前缀为I然后描述是错误的,因为它意味着实现可以有一个较短的名称。 IList(intf) - >列表。这是一个反模式,因为我们都知道我们应该使用intf,并且在创建时可能只是具体的类型。不要焚烧我这是一个概括,但前提是intf很少只是impl。实现名称应该描述它是如何实现intf或它正在做什么的。想一想使用链表实现List的List,LinkedList。谁在乎它是否更长,因为我们应该在大多数时间使用List。如果我们有一个实现了许多intf的类,我们可能不应该将所有intf作为阴影包含在类的真正目的中。在没有intf的情况下移除的东西是有道理的。例如,ppl通过名字给我打电话,而不是使用我的名字的人,兄弟,开发人员等是最具描述性的名称。我想如果一个类是impl一个简单的intf然后调用它的默认Intf,这使它成为ious这是Intf的默认实现。类的名称最终应该是人类可读的,几乎是描述其目的的短语。前缀代码等不是很好,因为我们与单词进行通信而不是代码。计算机不管怎样调用什么类,所以我们为什么命名,所以这些名称可以帮助我们和我们的同事。

#17


Most likely its to make it easily identifiable in intellisense, since all the interfaces will clump together. Similar to how I prefix all my UI controls with btn, tb, lb. When intellisense kicks in everything is clumped together in one easy group.

最有可能的是它可以在intellisense中轻松识别,因为所有接口都会聚集在一起。类似于我使用btn,tb,lb为我的所有UI控件添加前缀。当intellisense踢出所有内容时,在一个简单的组中聚集在一起。

#18


With all of the arguments about naming conventions and giving proper names to variables and methods that actually describe what they do...why not just name your interfaces (e.g. PetInterface, PlayerInterface, etc.) and do away with the prefix "I" all together. So what you have to type an additional 9 letters, at least the "I" is removed and we know it is not a class, because it says "Interface".

有了关于命名约定的所有参数,并给实际描述它们所做的变量和方法的专有名称......为什么不只是命名你的接口(例如PetInterface,PlayerInterface等)并取消前缀“I”all一起。所以你必须输入另外9个字母,至少删除“I”,我们知道它不是一个类,因为它说“接口”。