7
votes

In Delphi we can delegate the implementation of an interface to another class, I'm wondering if this is possible in C#?

For example, I have the interface IMyInterface and I say TMyClass implements IMyInterface. but actually it doesn't. Internally I can use the implements keyword to delegate the interface implementation to another class without having to declare every method in TMyClass.

5

5 Answers

6
votes

There is a simple answer: no, C# does not allow it in the same way as in Delphi.

For those knowing C# but not Delphi, this is what is meant: http://docwiki.embarcadero.com/RADStudio/en/Implementing_Interfaces , see the "Implementing Interfaces by Delegation (Win32 only)" section.

I guess you will have to pass the method calls to the interface manually. My C# is a litle bit rusty (I can still read it very well, though):

public class Blah : ISomeInterface
{
    public ISomeInterface implementer { getter and setter here }

    public int ISomeInterface.DoThis() 
    { 
        if (implementer) return implementer.DoThis(); 
    }
    public void ISomeInterface.DoThat(int param) 
    { 
        if (implementer) implementer.DoThat(param); 
    }

etc...

Where DoThis and DoThat are methods of ISomeInterface that must be implemented by Blah. In C#, you must explicitly delegate each of these methods to the contained interface. In Delphi, this is done automatically (i.e. the methods are generated and called behind the scenes, invisibly to the user), when you use the implements keyword after a property of a class or interface type.

I assume that some of the answerers are confused by the use of the terms implements and delegation, which have a different meaning in C#.

0
votes

I don't think there's any practical way. You could write the implementing class as an abstract class, which in turn becomes quite clumsy because you can no longer instantiate the first class. The only way is to write some ugly empty virtual methods, like so:

public interface ISomething
{
    void DoOne();
    void DoTwo();
}

public class Something : ISomething
{
    public virtual void DoOne() { }
    public virtual void DoTwo() { }
}

But this is a bad class design IMO, seeing as you should really have made the implementing class abstract in the first place, so people cannot instantiate an instance of the class that implements a bogus interface.

So the proper way would be to partially implement the interface within your "abstract" class, and delegate the others to inheriting classes by marking them as abstract (up to the deriving class to implement).

I.e

public interface ISomething
{
    void DoOne();
    void DoTwo();
}

public abstract class Something : ISomething
{
    public abstract void DoOne();
    public abstract void DoTwo();
}

This way, no-one can directly instantiate your unstable "Something" class, but the deriving classes are still required to implement the abstract methods of the interface that have not yet been implemented. This is far more robust and safe.

Point to note, if it's your OWN interface that you're implementing, scrap it. Write the interface as an abstract class to begin with and implement some of the methods, far easier.

0
votes

You could use partial classes:

// SomeThing.cs
public partial class SomeThing
{
   // your interface independant part
}

// SomeThing.ISomeThing.cs
public partial class SomeThing: ISomeThing
{
   // ISomeThing implementation
}

Those two files need to be in the same assembly. They get combined by the compiler to a single class.

0
votes

You could use a partial class, this will give you just a possibility to put implementation to a different files, both parts of class should be in the same assembly.

Class1.cs

public partial class Class1: IInterface {}

Class1Impl.cs

public partial class Class1 { /*implementation */ }

I can't imagine in my mind another way of doing what you want. Just use encapsulation =) it is not what you actually want, you have to write some stub proxy methods.

0
votes

In C# you cannot delegate the implementation of an interface for a class except through inheritance (see the answer from Nikola Anusev).

However you can use a partial class definition to seperate the interface implementation from the rest of the class.

In one (MyClass.Specific.cs) file you have :

public partial class MyClass
{
    void MySpecificMethod() {...}
}

And in the other file (MyClass.IMyInterface.cs) you only have your class specific methods:

public partial class MyClass : IMyInterface
{
    void IMyInterface.MySpecificMethod() {...}
}

You still have all the methods in MyClass but in distinct files.