[Mono-list] reusing interface implementation

Jonathan Pryor jonpryor at vt.edu
Tue May 27 09:19:36 EDT 2008


On Tue, 2008-05-27 at 12:53 +0200, Mathias Tausig wrote:
> I have a class hierarchy which is usable as it is. But now I would like to
> extend it with an interface and create something like a parallel
> hierarchy. But as far as I can see, it is not possible to implement my
> interface only once.
> A simple example what I mean:
> 
> 
> public class A{
>        public A(){}
>        public virtual int x{
> 	 get{return 1;}
>        }
> }
> public class B:A{
>        public override int x{
> 	 get{return 2;}
>        }
> }
> 
> public interface ITest{
>        void iF();
> }
> 
> public class AplusInterface :A,ITest{
>   public void iF(){
>     Console.WriteLine("x: "+x);
>   }
> }
> 
> And now I would like to have a class "BplusInterface" without having to
> implement the interface once again. Is that possible in C#?

So you want to do something like:

        class BplusInterface : B, AplusInterface {
        }

As you surmise, this isn't possible, as C# doesn't support inheritance
from more than one base class.

A workaround would be to not use inheritance in that fashion, and
instead use composition:

        public class Test : ITest {
                A a;
                
                public Test (A a)
                {
                        this.a = a;
                }
                
                public void iF()
                {
                        Console.WriteLine("x: "+a.x);
                }
        }

Since A.x is virtual, you can instantiate Test via `new Test (new B())`,
and when Test.iF() is invoked B.x will be invoked.

(This is also further proof that composition should be preferred to
inheritance, as composition is more flexible and (in other contexts)
less prone to breakage.)

Should `new Test (new B())` be too onerous, you could recruit generics
to make things "nicer":

        public class Test<T> : ITest
                where T : A, new()
        {
                A a = new T();
                
                public void iF()
                {
                        Console.WriteLine("x: "+a.x);
                }
        }

Though this would instead require `new Test<A>()` or `new Test<B>()`.

 - Jon




More information about the Mono-list mailing list