在C ++中,我经常需要NVI来获得API的一致性。不过,在C#中我没有看到它用得那么多。我想知道这是因为C#作为一种语言,提供的功能使得NVI不再需要吗? (尽管如此,我仍然在C#中使用NVI。)
答案 0 :(得分:8)
C#通过取消多重继承来解决NVI问题。虽然我认为多重继承会产生更多的邪恶而不是好的,但对于NVI来说(大多数情况下)是必要的。跳到脑海的最简单的事情是:C#中的一个类不能实现多个NVI。一旦发现C#/ NVI串联的这种令人不快的方面,放弃NVI比C#容易得多。
顺便说一下,谈论方面。这是一个非常有趣的概念,它的目标与NVI的目标完全相同,只是它试图查看问题的“真正的本质”,并“恰当地”解决它,可以这么说。 Take a look
就.NET Framework而言,有一种机制可以做到这一点:注入“正交”的代码,也就是说,注入手头的主要逻辑。我在谈论MarshalByRef / TransparentProxy的所有业务,我相信你已经听说过了。但它确实会严重影响性能,所以这里没有什么好运。
还有许多尝试通过其他技术实现相同的概念,从建筑外墙到上面提到的脏业务到MSIL的后期处理。
后一种方法恰好吸引了你的最多,因为它可以变得透明(通过将所需的步骤合并到一个构建例程中),它不会影响性能(实际执行“正交”不仅仅是绝对必要的“代码”并且它不涉及某种“黑客攻击”或逆向工程,因为MSIL是开放的并且有很好的文档记录。
Here可以更详细地找到这些要点,以及更多信息和实际工具的链接。使用Google也可以达到同样的目的。 : - )
祝你好运。答案 1 :(得分:5)
我认为解释只是在C#中,“传统的”Java风格的OOP更加根深蒂固,NVI与此背道而驰。 C#具有真正的interface
类型,而NVI依赖于实际上是基类的“接口”。无论如何,这就是用C ++完成的,所以它很适合。
在C#中,它仍然可以完成,它仍然是一个非常有用的习惯用语(更重要的是,我会说,比“普通”接口),但它要求你忽略内置的语言功能。
许多C#程序员不会认为NVI类是“适当的接口”。我认为这种精神抵抗是导致它在C#中不太常见的唯一原因。
答案 2 :(得分:4)
Trey Nash在他的书Accelerated C#中将NVI模式作为C#中的规范形式进行了宣传。
我不知道是谁写了你引用的文章(More C++ Idioms/Non-Virtual Interface),但我觉得作者错过了这一点。
...
我认为,哲学上,完全抽象的类(即没有任何实现)与接口之间没有什么区别(在C#中)。从表面上看,它们都可以提供可以执行的方法的签名,并且需要其他东西来实现该功能。
使用C#,如果您需要的是接口,您将始终编程到接口。您只使用(抽象)基类,因为您也希望实现重用。
除了提供类层次结构作为接口的默认实现之外,许多代码库还将这些和程序组合到接口。
如果你在C ++中使用NVI的唯一动机是拥有一个接口,那么不,你不会在C#中使用它,因为语言/ CLR提供接口作为一流的功能。
在我看来,NVI从来就不是关于接口的。它始终是实现template method模式的绝佳方式。
有用性体现在代码生命周期维护(易于更改,扩展等),并提供了更简单的继承模型。
我的观点:是的,NVI在C#中非常有用。
答案 3 :(得分:0)
我认为NVI在C#中和在C ++中一样有用。我看到它在我公司经常使用。