Explicit Interface Implementation with C#

With C#, interfaces can be implemented implicitly or explicitly. With implicit interface implementations, the members of the interface are public in the class. With explicit implementations, in the class the interface members are not declared as public members and cannot be directly accessed using an instance of the class, but a cast to the interface allows accessing the members. Let’s go into the details.

Usually I’m writing about new or upcoming features. This time I’m writing about C# feature that is available since the first version of C#. The plan is to have this part of an ongoing series on some classic features. However, showing the classic features, I’m also using new C# syntax where it applies (like here with a sample using C# 8 switch expressions).

Music Notes - C#

Implicit Interface Implementations

Interfaces are implemented implicit by declaring a public member in the class with the same signature of the method as defined in the interface and the same return type. This is how you normally implement interfaces.

public interface IFoo1
{
  void Foo();
}

public class FooImpl1 : IFoo1
{
  public void Foo() => 
    Console.WriteLine("ImplicitInterfaceImplementation.Foo");
}

Explicit Interface Implementation

Implementing interfaces explicitly, the interface is no longer declared public with the implementation, and the interface member is prefixed with the name of the interface:

public class FooImpl2 : IFoo1
{
  void IFoo.Foo() => Console.WriteLine("ExplicitInterfaceImplementation.Foo");
}

Using the implementation FooImpl2, the member of the interface cannot be used directly. A cast is needed to invoke the Foo method. Of course you can also use the is and as operators, or pass the instance to a method requiring an IFoo parameter:

static void Main()
{
  var f2 = new FooImpl2();
  // use a cast
  ((IFoo)f2).Foo();

  // use the is operator
  if (f2 is IFoo f)
  {
    f.Foo();
  }

  // the as operator
  (f2 as IFoo)?.Foo();

  // invoke a method with IFoo parameter
  DoIt(f2);
}

static void DoIt(IFoo foo)
{
  foo.Foo();
}

This is nice, but what is it good for?

Hiding Interface Implementations

One reason to use explicit interface implementations is to hide the members of the interface from a concrete class.

A concrete classic example is the class StringCollection implementing the interface IList. Both of these types are available before generics have been available. The IList interface defines a member with requiring an object parameter: int Add(object value); Of course, this is not the best option for the StringCollection. The StringCollection defines the method int Add(string value) which is preferred using strings. To still allow passing the StringCollection to methods requiring IList, some members of the interface IList are implemented explicitly.

Resolving Conflicts

Another reason is to resolve conflicts. Let’s get into the declaration of the IDataErrorInfo interface. This interface declares the Error property and an indexer:

public interface IDataErrorInfo
{
  string Error { get; }
  string this[string columnName] { get; }
}

The class MyCollection should implement this interface. However, the class already defines an indexer with a string parameter for another use case of the class – just not error handling. To fulfill the requirements of this interface, it can be implemented explicitly. Implementations making use of IDataErrorInfo (for example WPF), access the explicit implemented interface members:

public class MyCollection : IDataErrorInfo
{
  private Dictionary<string, string> _data = new Dictionary<string, string>();

  public string this[string key]
  {
    get => _data[key];
    set
    {
      if (_data.ContainsKey(key))
      {
        _data[key] = value;
      }
      else
      {
        _data.Add(key, value);
      }
    }
  }

  public int Data1 { get; set; }
  public int Data2 { get; set; }

  string? IDataErrorInfo.this[string columnName] =>
    columnName switch
    {
      nameof(Data1) => Data1 > 5 ? "error with Data1" : null,
      nameof(Data2) => Data2 > 3 ? "error with Data2" : null,
      _ => null
    };

  string IDataErrorInfo.Error => throw new NotImplementedException();
}

The implementation of the indexer for the interface IDataErrorInfo uses new C# 8 syntax – switch expression. In this scenario, the switch expression has a simpler and shorter implementation compared to the switch statement.

The same scenario applies having the same members defined with multiple interfaces, but the need to have different implementations. This can be resolved easily with explicit interface implementations.

Summary

With C# interfaces can be implemented implicit and explicit. Usually you’ll use implicit interface implementations, but there are good reasons when to use explicit implementations such as hiding interface members, but still having the contract implemented when it’s needed, and to resolve conflicts with different implementations needed for the same member.

If you’ve read this far, consider buying me a coffee which helps me staying up longer and writing more articles.

Buy Me A Coffee

More information on C# and .NET Core is in my book Professional C# 7 and .NET Core 2.0, and in my workshops.

Enjoy learning and programming!

Christian

Advertisements

4 thoughts on “Explicit Interface Implementation with C#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.