views:

231

answers:

4

In C++, I often needed NVI to get consistency in my APIs. I don't see it used as much among others in C#, though. I wonder if that is because C#, as a language, offers features that makes NVI unnecessary? (I still use NVI in C#, though, where needed.)

+2  A: 

I think NVI is as useful in C# as it is in C++. I see it used very frequently at my company.

Timores
+1  A: 

I think the explanation is simply that in C#, "traditional" Java-style OOP is much more ingrained, and NVI runs counter to that. C# has a real interface type, whereas NVI relies on the "interface" actually being a base class. That's how it's done in C++ anyway, so it fits naturally there.

In C#, it can still be done, and it is still a very useful idiom (far more so, I'd say, than "normal" interfaces), but it requires you to ignore a built-in language feature.

Many C# programmers just wouldn't think of a NVI class as being "a proper interface". I think this mental resistance is the only reason why it's less common in C#.

jalf
+1  A: 

C# poses a problem with NVIs by taking away multiple inheritance. While I do think that multiple inheritance generates more evil than good, it is necessary (in most cases) for NVI. The simplest thing that jumps to mind: a class in C# cannot implement more than one NVI. Once one discovers this unpleasant aspect of C#/NVI tandem, it becomes much easier to give up NVIs than C#.

And by the way, speaking about aspects. That's a very interesting concept, and it's aim is exactly the same as that of NVIs, only it attempts to look at the "true essense" of the issue and address it "properly", so to say. Take a look.

And as far as .NET Framework goes, there is a mechanism to do just that: inject code that is "orthogonal", so to say, to the main logic at hand. I'm talking about all that MarshalByRef/TransparentProxy business, I'm sure you've heard of it. It does seriously impact performance, though, so no big luck here.

There have also been numerous attempts to implement the same concept through other techniques, from building facades to the dirty business mentioned above to post-processing of MSIL.

The latter approach happens to appeal to yours truly the most, since it can be made transparent (by incorporating needed steps into one's build routine), it doesn't affect performance (more than is absolutely necessary to actually execute the "orthogonal" code) and it does not involve some kind of "hacking" or reverse engineering, since MSIL is open and well documented.

Here one can find these points discussed in more detail, as well as more information and links to actual tools. Using Google for the same purpose is also acceptable. :-)

Good luck.

Fyodor Soikin
Excellent answer.
Johann Gerell
+1  A: 

Trey Nash in his book Accelerated C# promotes the NVI pattern as a canonical form in C#.

I don't know who wrote the article you reference (More C++ Idioms/Non-Virtual Interface), but I feel the author missed the point.

...

Interface vs Abstract classes

I'd argue that, philosophically, there's little difference (in C#) between a fully abstract class (ie no implementation whatsoever) versus an interface. On the surface, they both can provide a signature of methods that can be performed and require something else to implement that functionality.

With C# you would always program to an interface if what you need is an interface. You only use an (abstract) base class because you also want implementation reuse as well.

Many code bases combine these and program to the interface in addition to providing a class hierarchy as a default implementation for the interface.

NVI for Interfaces in C

If your only motivation to use NVI in C++ would be to have an interface, then no, you're not going to use this in C# because the language / CLR provides interfaces as a first-class feature.

NVI and object hierarchies

In my mind, NVI has never been about interfaces. It's always been an excellent way to implement the template method pattern.

The usefulness manifests itself in code lifecycle maintenance (ease of change, extension, etc), and provides a simpler model of inheritance.

My opinion: Yes, NVI is very useful in C#.

Robert Paulson