docs
docs copied to clipboard
Should adding a static (non-virtual, non-abstract) member to an interface be considered breaking?
Type of issue
Other (describe below)
Description
Currently, adding a member to an interface is disallowed.
I would like to propose that adding a static non-abstract, non-virtual member to an interface (for runtimes that handle that) should be allowed.
For example, suppose the .NET team were to add a static property to IDisposable. Note that I've added the access modifiers just for clarity, and NoOpDisposable would be better as a singleton. In reality this would presumably have to only be exposed on particular runtimes as well - but let's consider a ".NET 8 only" world for now.
public interface IDisposable
{
public void Dispose();
public static IDisposable NoOp => new NoOpDisposable();
private class NoOpDisposable : IDisposable
{
public void Dispose() {}
}
}
You could then write:
IDisposable x = IDisposiable.NoOp;
I think that shouldn't count as a breaking change. (Motivation: I have a PR for Noda Time which in its current form does this for IClock: https://github.com/nodatime/nodatime/pull/1816 - the ApiCompat tooling treats this as a breaking change.)
Is there a scenario I'm missing where this would be a breaking change (binary or source)?
Page URL
https://learn.microsoft.com/en-us/dotnet/core/compatibility/library-change-rules#members
Content source URL
https://github.com/dotnet/docs/blob/main/docs/core/compatibility/library-change-rules.md
Document Version Independent Id
79a4adc9-b2c9-68b7-669e-2bd8d2d44faf
Article author
@gewarren
Metadata
- ID: c4b482b0-6dd1-42de-5389-5b0b47823402
- Service: dotnet-fundamentals
Adding @stephentoub and @terrajobst for thoughts.
Should this be considered a breaking change. If so, why?
It's a breaking change in the sense that it raises your minimum .NET to .NET 6. For anyone on .NET 6 and higher, I don't believe it's a breaking change.
Making it virtual probably can be a breaking change, just like any DIM can be (if the runtime can't find a single best match). To some extent this problem is a bit like saying adding a member to any type can be a breaking change because it might change which member is called depending on the hierarchy the customer built (or when the customer uses reflection).
While I don't think there are on the exact some point on the breaking change spectrum, I do think we should consider both of them acceptable in order to allow ourselves to advance.