Search code examples
c#.netclrgac-msil

Is there a difference between implementing an interface vs adding a new method?


As shown in the code below, there are two interfaces IFoo defined in two different assemblies:

/// assembly A
interface IFoo {
    void DoSomething()
}

/// assembly B
interface IFoo {
    void DoSomething()

    void DoSomethingElse()
}

/// assembly C
class Bar : IFoo {
    public virtual void DoSomething()

    public virtual void DoSomethingElse()
}

Assuming assembly A and assembly B mistakenly have the same signature (either assembly weak name or strong name). Will the generated MSIL for class Bar be different depending on whether assembly A or assembly was used during build time?

In other words, suppose we build a project with assembly A and C at run time, is it okay to replace A with assembly B at run time? Or I will get exceptions like "IFoo.DoSomethingElse" is not implemented because during build process DoSomethingElseis considered a new method as opposed to implementing an existing method in the interface.


Solution

  • Interface mappings are created at build time and if "assembly A" (1 method) used at build time than Foo class will only map one method in its interface map.

    When instance of the class is created it will try to use the interface available at run time (which not necessary the same as one used at compile time as in your case) and will fail to map the new second method.

    There is really no good way to solve it prior C# 8 - you either have to downgrade dependency so its interface is backward compatible or recompile your code with new version of dependency.

    If this is expected to be common problem you may consider exposing base class from "assembly A" with default implementations of methods to allow adding methods to interface and derive your Foo from that class instead of interface.

    As Hans Passant pointed out C# 8 introduces default interface methods to solve that exact problem.