Search code examples
c#interface.net-7.0

Why static members in interfaces are not enforced?


With C# 11 and .NET 7 we can define static members in interfaces, but why is it that the class which implements this interface

public interface IHasInstance<T>
{
    static T Instance { get; set; }
}

isn't enforced to have a static property name Interface such as

internal static MyClass Instance { get; } = new();

EDIT: I actually wanted to know how to enforce implementing the static member defined in the interface and I wasn't aware I have to use the abstract modifier to make it work that way.


Solution

  • Because static T Instance { get; set; } is not a part of an interface contract, it is part of (yep, it sounds strange, but) interface implementation: ability to specify static fields, methods, properties, indexers, and events was added in C# 8 with default implementations in interfaces feature:

    The syntax for an interface is extended to permit

    • ...
    • member declarations that declare static fields, methods, properties, indexers, and events;
    • ...

    Interfaces may not contain instance state. While static fields are now permitted, instance fields are not permitted in interfaces. Instance auto-properties are not supported in interfaces, as they would implicitly declare a hidden field.

    Note that the main goal of this particular addition is:

    Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.

    C# 11 actually has another feature added which allows to achieve your goal - abstract static members in interfaces:

    public interface IHaveInstance<T>
    {
        static abstract T Instance { get; set; }
    }
    
    class Bar : IHaveInstance<Bar>
    {
        // now is required
        public static Bar Instance { get; set; } = new();
    }
    

    Another feature added with C# 11 in .NET 7 is generic math which actually heavily utilizes abstract static members.