Expressingx
Expressingx

Reputation: 1572

How does multiple Interface inheritance works in C#?

I'm learning ASP.NET Core 2 and a question came to my mind. How does Interface instance gives difference implementations?

Lets get IServiceCollection. It has various methods like AddMvc(), AddDbContext<T>() etc. Checking the source code IServiceCollection doesn't have any methods that has to be implemented if someone implements it. It simply inherits IList<ServiceDescriptor> and the inheritance chain of IList < ICollection < IEnumerable

Ok, went to see ServiceDescriptor but the class doesn't implement any interface and in it there is no method implementations like AddMvc(), AddDbContext<T>

Then how and from where do these methods come from ? How it works behind the scenes?

I'm really trying to learn OOP, but I think I miss some basics.

Upvotes: 1

Views: 328

Answers (2)

user47589
user47589

Reputation:

The trick here is that interfaces can have extra methods tacked on. In C# we do this using extension methods. Here is a basic example:

public interface IFoo 
{
    int GetFoo();
}

public class Foo : IFoo 
{
    public int GetFoo()
    {
        var foo = ... // does something to get a foo
        return foo;
    }
}

public class Program
{
    public static void Main()
    {
        IFoo theFoo = new Foo();
        theFoo.PityTheFoo();       // wait, what?  
    }
}

Now at this point I can hear you saying "Amy! Hold on! IFoo doesn't have a method that does any kind of pitying!" And you would be right. Pretend for a moment that you don't own the source code for IFoo. How can you add a method to IFoo? Or, suppose you do own the source for IFoo, and want to add a method without having to modify every class that implements that interface?

This is where extension methods come in:

public static class FooExtensions 
{
    public static void PityTheFoo(this IFoo foo)
    {
        // pities the foo
    }
}

Note the this keyword inside the function declaration. That indicates this is an extension method. It tacks our PityTheFoo method onto the interface. Classes that implement the IFoo interface do not need to implement PityTheFoo(). If you had one hundred different Foo classes, all implementing this interface, none of them will require modification.

Extension methods aren't part of the inheritance chain. When the compiler reaches the commented line in Program, this is what it "pretends" the code looks like:

public class Program
{
    public static void Main()
    {
        IFoo theFoo = new Foo();
        FooExtensions.PityTheFoo(theFoo);
    }
}

Why would we want this?

  • You don't own the interface, but want to add operations to it.
  • You own the interface, but the numerous classes that implement that interface can share the same implementation, sort of like they inherited it.
  • The interface might be part of a library. If you add a method to it, people who use your library will find their code broken until they add the method to their classes. Extension methods let you avoid the breaking change.

Upvotes: 2

Dai
Dai

Reputation: 155588

AddMvc(), AddDbContext() etc are Extension Methods: a different syntax for invoking a static function defined in a totally different class that has the System.Runtime.CompilerServices.ExtensionAttribute (aka [Extension]) applied to it (in C#, an extension method can be written by putting the this modifier before the first parameter.

If you use the "Go to definition" feature in VS for those methods you'll see they're defined on Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc: https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.mvcservicecollectionextensions.addmvc?view=aspnetcore-2.0

Upvotes: 0

Related Questions