Skip to main content

Internal Interface Classes in C#

In C#, interfaces can only specify public properties and functions. However, especially when making libraries to be used by other projects, it is often beneficial to have internal interfaces (specifying functions that should also be marked internal, rather than public). Below is an outline of how to get this sort of desired visibility for internal interfaces, as well as convenient syntax for using internal interface methods.

Let's say you have an internal interface that you want to use:

internal interface IInterface
{
    string InternalProperty { get; }
    void InternalMethod();
}

Even though the interface is marked internal, interfaces can only specify public members, meaning that any classes that implement this interface implicitly need to declare InternalMethod() and InternalProperty as public. This is often not what you want to do, since the internal interface is often specifying functions that should also only be accessed internal to the library (DLL).

The solution to this dilemma is to explicitly implement the interface:

public class MyExternalClass : IInterface
{
    string IInterface.InternalProperty
    {
        get { ... }
    }

    void IInterface.InternalMethod()
    {
        ...
    }
}

This approach is even mentioned in passing on MSDN:

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.

However, this approach has the disadvantage that now, if you want to call one of the internal interface methods, you must explicitly cast implementing classes to IInterface. One way to solve this would be to make wrapper methods that simply call these interface methods and mark those as internal, but that would be a decent amount of extra boilerplate to add to each implementing class.

There is a better way. Thanks to C#'s extension classes, we can make our lives easy and explicit-cast-free:

internal static class IInterfaceExtensions
{
    public static void InternalMethod(this IInterface iface)
    {
        iface.InternalMethod();
    }

    public static string GetInternalProperty(this IInterface iface)
    {
        return iface.InternalProperty;
    }
}

This is a bit of extra code that needs to be done for each method, and even more for each property (since extension properties aren't supported i.e. you need to define getter and setter methods), but the benefit is that now with any instances of implementors of the internal interface IInterface, you can just use instance.InternalMethod() rather than ((IInterface)instance).InternalMethod(). In my opinion, it is definitely worth the extra boilerplate code to define the extension methods if you're going to be accessing the internal methods in any more than one place. It's also a lot less code than adding the wrapper methods in each implementing class!

This even makes calling the methods from within the implementing class's instance easier. Normally you'd have to use ((IInterface)this).InternalMethod(), but with this approach, you can simply use this.InternalMethod() and it will use the extension method (unfortunately this is required, just because of how extension methods are matched by the C# parser).

Happy interfacing!

Comments