6

在 C++ 中,我经常需要NVI来获得 API 的一致性。不过,我认为它在 C# 中的使用并不多。我想知道这是否是因为 C# 作为一门语言提供了不需要 NVI 的功能?(不过,在需要的地方,我仍然在 C# 中使用 NVI。)

4

4 回答 4

8

C# 通过取消多重继承给 NVI 带来了问题。虽然我确实认为多重继承产生的恶多于善,但它(在大多数情况下)对于 NVI 来说是必要的。想到的最简单的事情是:C# 中的一个类不能实现多个 NVI。一旦发现 C#/NVI 串联的这个令人不快的方面,放弃 NVI 就比 C# 容易得多。

顺便说一下,谈到方面。这是一个非常有趣的概念,它的目标与 NVI 的目标完全相同,只是它试图看到问题的“本质”并“正确”解决它,可以这么说。看一看

就 .NET Framework 而言,有一种机制可以做到这一点:将“正交”代码注入手头的主要逻辑。我说的是 MarshalByRef/TransparentProxy 的所有业务,我相信你已经听说过。但是,它确实会严重影响性能,所以这里没有太大的运气。

也有许多尝试通过其他技术来实现相同的概念,从建筑立面到上面提到的肮脏业务再到 MSIL 的后处理。

后一种方法恰好最能吸引您,因为它可以变得透明(通过将所需的步骤合并到一个构建例程中),它不会影响性能(超过实际执行“正交”代码所绝对必要的)它不涉及某种“黑客”或逆向工程,因为 MSIL 是开放的并且有据可查。

在这里可以找到更详细讨论的这些要点,以及更多信息和实际工具的链接。出于相同目的使用 Google 也是可以接受的。:-)

祝你好运。

于 2010-02-26T19:44:57.933 回答
5

我认为解释很简单,在 C# 中,“传统”Java 风格的 OOP 更加根深蒂固,而 NVI 与此背道而驰。C# 有一个真正的interface类型,而 NVI 依赖于实际上是一个基类的“接口”。无论如何,这就是它在 C++ 中的完成方式,因此它很自然地适合那里。

在 C# 中,它仍然可以完成,它仍然是一个非常有用的习惯用法(我想说,比“普通”接口更有用),但它要求您忽略内置的语言功能。

许多 C# 程序员只是不认为 N​​VI 类是“适当的接口”。我认为这种心理阻力是它在 C# 中不太常见的唯一原因。

于 2010-02-26T12:28:13.257 回答
4

Trey Nash在他的Accelerated C#一书中将 NVI 模式提升为 C# 中的规范形式。

我不知道你参考的文章是谁写的(More C++ Idioms/Non-Virtual Interface),但我觉得作者没有抓住重点。

...

接口与抽象类

我认为,从哲学上讲,完全抽象的类(即没有任何实现)与接口之间几乎没有区别(在 C# 中)。从表面上看,它们都可以提供可以执行的方法的签名,并且需要其他东西来实现该功能。

如果您需要的是接口,则使用 C# 总是会编程到接口。您只使用(抽象)基类,因为您还希望实现重用。

除了提供类层次结构作为接口的默认实现之外,许多代码库将这些和程序结合到接口中。

C 中接口的 NVI

如果您在 C++ 中使用 NVI 的唯一动机是拥有一个接口,那么不,您不会在 C# 中使用它,因为语言 / CLR 将接口作为一流的特性提供。

NVI 和对象层次结构

在我看来,NVI 从来就不是关于接口的。它一直是实现模板方法模式的绝佳方式。

有用性体现在代码生命周期维护(易于更改、扩展等)中,并提供了更简单的继承模型。

我的意见:是的,NVI 在 C# 中非常有用。

于 2010-09-15T03:00:22.087 回答
0

我认为 NVI 在 C# 中和在 C++ 中一样有用。我看到它在我的公司经常使用。

于 2010-02-26T09:37:14.987 回答