When it comes to extending a published interface with additional functionality, when is a default interface member preferable to creating an extension method or creating a second interface that derives from the first and adds additional members? The following factors should be considered when making this decision:
In summary, adding property polymorphic behavior is only possible with a second interface or default interface members. When only methods, and not properties, are part of the updated interface, extension methods are preferred.
Interfaces introduce another category of data types. (They are one of the few categories of types that don’t extend System.Object.9) Unlike classes, however, interfaces can never be instantiated. An interface instance is accessible only via a reference to an object that implements the interface. It is not possible to use the new operator with an interface; therefore, interfaces cannot contain any instance constructors or finalizers. Prior to C# 8.0, static members are not allowed on interfaces.
Interfaces are similar to abstract classes, sharing such features as the lack of instantiation capability. Table 8.2 lists additional comparisons. Given that abstract classes and interfaces have their own sets of advantages and disadvantages, you must make a cost–benefit decision based on the comparisons in Table 8.2 and the guidelines that follow to make the right choice.
Abstract Classes |
Interfaces |
Cannot be instantiated directly, but only by instantiating a non-abstract derived class. |
Cannot be instantiated directly, but only by instantiating an implementing type. |
Derived classes either must be abstract themselves or must implement all abstract members. |
Implementing types must implement all abstract interface members. |
Can add additional non-abstract members that all derived classes can inherit without breaking cross-version compatibility. |
Can add additional default interface members in C# 8.0/.NET Core 3.0 that all derived classes can inherit without breaking cross-version compatibility. |
Can declare methods, properties, and fields (along with all other member types, including constructors and finalizers). |
Instance members are limited to methods and properties, not fields, constructors, or finalizers. All static members are possible, including static constructors, static events, and static fields. |
Members may be instance or static, and optionally abstract, and may provide implementations for non-abstract members that can be used by derived classes. |
Starting with C# 8.0/.NET Core 3.0, members may be instance, abstract, or static, and may provide implementations for non-abstract members that can be used by derived classes. |
Members may be declared as virtual or not. Members that should not be overridden (see Listing 8.13) would not be declared as virtual. |
All (non-sealed) members are virtual, whether explicitly designated as such or not; therefore, there is no way for an interface to prevent overriding the behavior. |
A derived class may derive from only a single base class. |
An implementing type may arbitrarily implement many interfaces. |
Static abstract members are not supported. |
C# 11 introduced static abstract members. |
In summary, assuming a .NET Core 3.0 framework is acceptable, C# 8.0 (or later) defined interfaces have all the capabilities of abstract classes except the ability to declare an instance field. Given that an implementing type can override an interface’s property to provide storage, which the interface then leverages, interfaces virtually provide a superset of what an abstract class provides. Furthermore, interfaces support a more encapsulated version of protected access in addition to multiple inheritance. Regardless, default interface members are intended for versioning not polymorphism so use caution when leveraging them for the latter.
C# 11 added support for static abstract members that would be included in the contract that implementing interfaces would need to implement. Since these don’t become fully functional without generics, we postpone a discussion on this topic until Chapter 12.
________________________________________