How can we use default implementation of different interfaces?

151 views Asked by At

As I know, I need to upcast an instance of an inherited class to the interface where a needed method is implemented and then call it.

interface IProcess
{
    void Do() { Console.WriteLine("doing"); }
    //...
}

interface IWait
{
    void Wait() { Console.WriteLine("waiting"); }
    //...
}

class Example : IProcess, IWait { }


static void Main(string[] args)
{
    Example item = new Example();
    (item as IProcess).Do();
    (item as IWait).Wait();
}

What if there are few interfaces with default implementation of different methods that I need? Is there some pattern that can solve this or maybe I should always use as keyword to call a method of a certain interface?

3

There are 3 answers

0
Guru Stron On BEST ANSWER

Another option in addition to @DavGarcia's answer - introduce an interface combining the needed ones and upcast to it:

interface IExample : IProcess, IWait { }    
class Example : IExample { }

IExample item = new Example();
item.Do();
item.Wait();
3
John Wu On

You can override the methods in the implementing class and pass through control to the default implementation.

interface IProcess
{
    void Do() { Console.WriteLine("doing"); }
}

interface IWait
{
    void Wait() { Console.WriteLine("waiting"); }
}

class Example : IProcess, IWait 
{
    public void Do() => ((IProcess)this).Do();

    public void Wait() => ((IWait)this).Wait();
}

Now you can do this:

static void Main(string[] args)
{
    Example item = new Example();
    item.Do();
    item.Wait();
}
1
DavGarcia On

If you are only calling the method once, I would do it like below. As ugly as it is, it is correct.

((IProcess)item).Do();

There are some other options that may be cleaner if you need to call more than once. You can convert to the interface:

IProcess itemProcess = item;
itemProcess.Do(); // Now call many times.

Usually though, I think you would be passing the object into a function that expects the interface:

void DoSomething(IProcess itemProcess) {
    itemProcess.Do();
}

DoSomething(item);