11 Oct 2009

In C#, you can explicitly implement interface members in your class or struct. C# language specification explains it better than I can:

For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name.

Here’s a small example:

public interface IMyInterface
{
    String SayHello();
}

class MyClass : IMyInterface
{
    string IMyInterface.SayHello()
    {
        return "Hello from IMyInterface!";
    }
}

The MyClass explicitly implement the SayHello method from IMyInterface. The interesting thing about explicitly implemented member is that they're only accessible when accessed trough the interface. From C# language specification again:

It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

The below code won’t compile, as the SayHello method is only visible trough the interface:

var o = new MyClass();

Console.WriteLine("MyClass: {0}", o.SayHello());

‘MyClass' does not contain a definition for 'SayHello' and no extension method 'SayHello' accepting a first argument of type 'MyClass' could be found (are you missing a using directive or an assembly reference?)

Now, let’s add a second method called SayHello with the exact same signature to the class, defined as such:

public string SayHello()
{
    return "Hello from MyClass";
}

This time, the previous code will compile, and will print “Hello from MyClass” in the console.

To access the explicitly implemented method, we have to go trough the interface, calling it as such:

var p = (IMyInterface)o;

Console.WriteLine("IMyInterface: {0}", p.SayHello());

This will print “Hello from IMyInterface” in the console, as expected.

The two primary purpose of explicit interface implementation, as described in the C# language specification, are twofold:

  • Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct.
  • Explicit interface member implementations allow disambiguation of interface members with the same signature. Without explicit interface member implementations it would be impossible for a class or struct to have different implementations of interface members with the same signature and return type, as would it be impossible for a class or struct to have any implementation at all of interface members with the same signature but with different return types.

On top of this, a common usage, as described in C# in Depth (2.2.2, page 46), is to palliate the lack of covariant return types (the example is on IClonable interface, see this topic on Stack Overflow).

C# 4.0 and dynamic keyword

With the new dynamic keyword in C# 4.0, a method call on a dynamic object is resolved at runtime. Is is therefore impossible to access the explicitly implemented member on a dynamic object.

dynamic q = new MyClass();
dynamic r = (IMyInterface)q;

Console.WriteLine("MyClass: {0}", q.SayHello());
Console.WriteLine("IMyInterface: {0}", r.SayHello());

The above code will print “Hello from MyClass” twice, as SayHello is called on a object who’s runtime type is MyClass. The only way to access IMyIntergace’s SayHello implementation is to cast q or r to IMyInterface before the call:

Console.WriteLine("IMyInterface: {0}", ((IMyInterface) q).SayHello());



blog comments powered by Disqus