gpt4 book ai didi

c# - 接口(interface)/抽象类编码标准

转载 作者:太空狗 更新时间:2023-10-29 19:55:13 26 4
gpt4 key购买 nike

我发现了一个提议的 C# 编码标准,其中声明“尝试为所有抽象类提供一个接口(interface)”。有人知道这样做的理由吗?

最佳答案

.NET Framework Design Guidelines 关于接口(interface)和抽象类有一些有趣的说法。

他们特别指出,在 API 的发展方面,接口(interface)的主要缺点是不如类灵活。一旦你发布了一个接口(interface),它的成员就永远固定了,任何添加都会破坏与实现该接口(interface)的现有类型的兼容性。然而,运送一个类(class)提供了更大的灵 active 。可以随时添加成员,即使在初始版本发布之后,只要他们不是抽象的。任何现有的派生类都可以继续不变地工作。以Framework中提供的System.IO.Stream抽象类为例。它最初不支持超时挂起的 I/O 操作,但 2.0 版能够添加支持此功能的成员,甚至来自现有的子类。

因此,为每个抽象基类提供相应的接口(interface)几乎没有其他好处。该界面不能公开,否则您将在版本控制方面回到原点。而且,如果您只公开抽象基类,那么一开始就拥有接口(interface)几乎没有什么好处。

此外,这一点通常有利于接口(interface),它们允许将契约与实现分开。 Krzysztof Cwalina 认为这种说法是似是而非的:它错误地假设您不能使用类将契约(Contract)与实现分开。通过编写驻留在与其具体实现不同的程序集中的抽象类,很容易实现相同的分离优点。他写道:

I often hear people saying that interfaces specify contracts. I believe this is a dangerous myth. Interfaces, by themselves, do not specify much beyond the syntax required to use an object. The interface-as-contract myth causes people to do the wrong thing when trying to separate contracts from implementation, which is a great engineering practice. Interfaces separate syntax from implementation, which is not that useful, and the myth provides a false sense of doing the right engineering. In reality, the contract is semantics, and these can actually be nicely expressed with some implementation.

一般来说,所提供的指南是DO favour defining classes over interfaces。 Krzysztof 再次评论:

Over the course of the three versions of the .NET Framework, I have talked about this guideline with quite a few developers on our team. Many of them, including those who initially disagreed with the guideline, have said that they regret having shipped some API as an interface. I have not heard of even one case in which somebody regretted that they shipped a class.

第二条准则认为,务必使用抽象类而不是接口(interface)来将契约与实现分离。这里的要点是,正确设计的抽象类仍然允许在契约和实现之间实现与接口(interface)相同程度的解耦。因此,Brian Pepin 的个人观点是:

One thing I've started doing is to actually bake as much contract into my abstract class as possible. For example, I might want to have four overloads to a method where each overload offers an increasingly complex set of parameters. The best way to do this is to provide a nonvirtual implementation of these methods on the abstract class, and have the implementations all route to a protected abstract method that provides the actual implementation. By doing this, you can write all the boring argument-checking logic once. Developers who want to implement your class will thank you.

也许最好的做法是重新审视经常被吹捧的“规则”,即派生类表示与基类的 IS-A 关系,而实现接口(interface)的类具有 与该接口(interface)的 CAN-DO 关系。要提出一个人应该总是编写接口(interface)和抽象基类的代码,而不管这样做的具体原因,似乎没有捕获要点。

关于c# - 接口(interface)/抽象类编码标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4790740/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com