1

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?

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Roman
  • 21
  • 1
  • 5
  • `as` folowed by `.` doesn't make sense. Either do a standard cast if you're sure of interface existence, or use `.?` if you're not – Charlieface Jan 25 '21 at 22:41

3 Answers3

3

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();
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
1

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);
DavGarcia
  • 18,540
  • 14
  • 58
  • 96
  • 1
    It seems that you can even declare an extension method [with the same signature](https://dotnetfiddle.net/Z6IGZo) and it will work – Guru Stron Jan 25 '21 at 22:48
1

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();
}
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Actually you can't - it will end with SO. AFAIK there are no way ATM to call default interface in it's implementation, only some [workarounds](https://stackoverflow.com/a/62334580/2501279) – Guru Stron Jan 25 '21 at 23:47
  • Are you sure? See [this accepted answer](https://stackoverflow.com/a/57761990/2791540). – John Wu Jan 26 '21 at 00:38
  • Yes, I am. In this answer default interface is called in another method, not in the implementation of itself. – Guru Stron Jan 26 '21 at 05:41