非虚拟接口(NVI)习惯用法在C#和C ++中一样有用吗?

在C ++中,我经常需要NVI来获得API的一致性。 不过,在C#中我没有看到它用得那么多。 我想知道是不是因为C#作为一种语言,提供的function使NVI变得不必要了? (尽管如此,我仍然在C#中使用NVI。)

我认为解释只是在C#中,“传统的”Java风格的OOP更加根深蒂固,NVI与此背道而驰。 C#具有真实的interface类型,而NVI依赖于“接口”实际上是基类。 无论如何,这就是用C ++完成的,所以它自然适合。

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

许多C#程序员都不会认为NVI类是“一个合适的接口”。 我认为这种精神抵抗是C#不太常见的唯一原因。

C#通过取消多重inheritance来解决NVI问题。 虽然我认为多重inheritance产生的不仅仅是好的,但对于NVI来说(大多数情况下)是必要的。 跳到脑海的最简单的事情是:C#中的一个类不能实现多个NVI。 一旦发现C#/ NVI串联的这种令人不快的方面 ,放弃NVI比C#容易得多。

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

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

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

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

在这里可以找到更详细讨论的这些要点,以及更多信息和实际工具的链接。 使用Google也可以达到同样的目的。 🙂

祝好运。

Trey Nash在他的书“ Accelerated C#”中将NVI模式作为C#中的规范forms进行了推广。

我不知道是谁写了你引用的文章( 更多C ++成语/非虚拟接口 ),但我觉得作者错过了这一点。

接口与抽象类

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

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

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

C语言接口的NVI

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

NVI和对象层次结构

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

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

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

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