Re: Declaring a Constructor in an Interface?

From: Ian Griffiths [C# MVP] (ian-interact-sw_at_nospam.nospam)
Date: 09/15/04


Date: Wed, 15 Sep 2004 12:36:21 +0100


> Well, in that case I have to apologize if i was wrong.
> However, i have read many places that an interface is faster than
> an abstract class. This is one of them:
> http://www.dotnetspider.com/Technology/KB/ShowSample.aspx?SampleId=492
>
> I wont argue with You,

Please feel free to argue with me. I think it's important to question
pretty much anything you read... (Otherwise, you're liable to be mislead.
There's an awful lot of rubbish out there on the web. That site you linked
to contains false information, for example. Unless you habitually question
everything and work out for yourself what's true, you won't recognize
falsehoods when you see them. I'm pretty sure that I'm right here, but
don't just take my word for it. :-) )

This is why I posted some runnable code that produces real test results in a
repeatable way - I think that's a whole lot more informative than
unjustified rules of thumb that say X is always faster than Y. I may be
right and I may be wrong, but the test shows what the test shows. (My
interpretation of the test results could also be wrong of course. I don't
think it is, but if you see problems, let's discuss them!)

And feel free to pick holes in my test code. It may be that it doesn't
accurately reflect the behaviour you'll see in your code. Ultimately, you
have to test for the kind of work your actual code will be doing. This is
the only reliable way of deciding performance questions. Microbenchmarks
like this aren't all that useful when it comes to writing real code.

> but would You also claim that an abstract class containing only abstract
> members
> is faster than an interface as well? In that case, what is the benefit of
> interfaces anyway?

First of all, I think the speed is almost completely irrelevant. The
differences I measured were only on the order of around 10%. But of course
the methods being invoked were empty. In practice, the difference will be
lost in the noise as soon as you put something inside there. (Indeed the
first version of the test I wrote spent more time checking the current time
than it did calling the methods, and there was no measureable performance
difference!)

So for all practical purposes, the difference in speed between abstract base
classes and interfaces is so small that you can ignore it for the vast
majority of scenarios. (And in any case, the difference is smaller still in
the next version of .NET.)

So the right question to be asking is: what fits best for your design? ABCs
or interfaces? Which expresses the structure and concepts in your system
with the most clarity? That's going to be far more important than which runs
fastest for most situations.

So what are the pros and cons?

Interfaces have the distinct benefit that a single class can implement
multiple interfaces. Abstract base classes don't have that feature - you
can only have a single base class. (In fact that's one big reason for
having interfaces at all. In C++, which doesn't restrict you to having a
single base class, there never was any specific notion of an interface,
because you could get exactly the same idiom through the use of abstract
base classes. That's all the COM interfaces were, for example. The only
reason Managed Extensions for C++ introduces interfaces is because the .NET
type system requires it.)

On the other hand, ABCs offer two advantages. First, they enable you to add
in some helper implementation. For example, if you derive from XmlReader,
not only does that mean that your class provides the XmlReader API, it also
means you get a certain amount of help: you are not obliged to implement the
entire thing from scratch.

That's not that great an advantage because you can actually offer this in
conjunction with interfaces - for each interface just declare an optional
base class that provides a partial implementation....

The more important difference with ABCs is that they version better. If you
want to release a new version of an API where you would like to add a new
method to an interface, you can't. If you add a new method, any existing
implementations are now broken, because they don't supply this new method.
But with an ABC, you can supply a default implementation of the method in
the base class. It might throw a NotImplementedException, but that will
only cause a problem if something tries to use the method. Existing code
that didn't even know the method existed clearly isn't going to do that...

The big problem with interfaces here is that they are completely abstract,
and the implementor is obliged to implement everything, and an upshot of
this is that interfaces are effectively immutable - you can't change them
without breaking stuff. (Unless you happen to be in a position to change all
of the classes that implement the interface. And if the interface was
defined as part of some public API, you won't own all the implementations!)

The standard solution was to introduce new interfaces - hence all the
IDispatchEx, IFoobar2, ISpong3 and so on that you see in old COM APIs.

The design guidelines for .NET Framework Class Libraries explicitly
recommend not using interfaces for this very reason. (Brad Abrams, who owns
those guidelines, hates the ISomething2 ISomething3 etc phenomenon and is
keen to avoid it in .NET.)

For what it's worth, I slightly prefer the flexibility interfaces offer. And
since I'm not in the habit of writing platforms that other people use,
versioning of public APIs is not really an issue for me. Interfaces tend to
be internal to my own code, in which case none of the above is really a
problem. If I want to change my interface, I can do that because I own all
the implementations...

So that's why we have both - sometimes one is better, sometimes the other is
better. It depends on what you are doing.

-- 
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/ 


Relevant Pages

  • Re: Pointer to "base" type - what does the Standard say about this?
    ... Since the `api' is the first element ... in each struct, it is always safe to convert the struct pointer to ... all of my implementations can (and in fact ... The interfaces are used by the rest of the ...
    (comp.lang.c)
  • Re: Abstract Class Theory
    ... >> there would be no need for abstract methods, and no abstract classes. ... >> the derived class will be overriding, or even overloading, the base class ... > class inherit from both. ... Actually you are confusing abstract classes and interfaces. ...
    (microsoft.public.dotnet.languages.csharp)
  • Exposing internal members of an assembly
    ... I am trying to have a set of base classes and interfaces of an ... the abstract classes and interfaces. ... The problem is that some parts of the API are "internal" in the sense ... the implementations will not be able to access ...
    (microsoft.public.dotnet.languages.csharp)
  • Exposing C# to COM / Inheritance of objects/interfaces
    ... I have ComVisible set to true for the entire assembly. ... I have base class A. ... There are interfaces IA and IAEvents for accessing properties of this object ...
    (microsoft.public.dotnet.framework.interop)
  • IGNORE - Re: Exposing COM & inheritance problems
    ... I have base class A. ... There are interfaces IA and IAEvents for accessing properties of this ... object and exposing events. ... when I then add a IBEvents (deriving from IAEvents) and change ...
    (microsoft.public.dotnet.languages.vc)

Quantcast