[Open issue]: static abstract interfaces and static classes · Issue #5783 · dotnet/csharplang (original) (raw)

With static abstract interface methods, consider:

using System;

public class C : IMethods { public static void M() { } }

internal interface IMethods { static abstract void M(); }

This compiles fine. However, if I try to make C be a static class:

using System;

public static class C : IMethods { public static void M() { } }

internal interface IMethods { static abstract void M(); }

it fails to compile with:

error CS0714: 'C': static classes cannot implement interfaces

Such an error arguably made sense before static abstract interface methods, as interface methods could only be instance members, and static classes can't have instance members (and even for an empty interface, you can't create instances of a static class and thus couldn't even use the interface as a typical marker used with is casts).

However, with static abstract interface methods, you can have an interface entirely composed of static abstract members, and it would logically make sense to have a static class implement that interface.

We could address this by either:

  1. Simply removing the error and allowing static classes to implement interfaces. If you try to implement one that has instance members, you won't be able to given the class is static, and you'll get errors about not fully implementing the interface.
  2. Allowing interfaces to be marked as static interface such that it can only contain static abstract members and not instance members, and then allow static classes to implement static interfaces.

One of the reasons one might want a static class implementing a static interface is to be able to then use that static class as a generic type argument. However, that is also prohibited by the language today, e.g. this:

using System;

public static class C { public static void M() { } }

class D { public static void M1(){}

public static void M2() => M1<C>();

}

results in:

error CS0718: 'C': static types cannot be used as type arguments

We should also consider lifting this constraint.

If we do lift it, then it becomes possible for a generic type or method to create locals, fields, etc. of that generic type, which could be a static class. Those members or locals would then be useless, since you wouldn't have a way to create an instance of them nor invoke anything off of them. If that's something we want to avoid, we could go with option (2) above, allow static classes to be used as a generic type argument when that argument is constrained to a static interface, and then language rules around static types (extended from classes to interfaces) should naturally prevent creating such members and locals.

Design Meetings

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-16.md#static-abstract-interfaces-and-static-classes