ECMA-334: 20.4.1 Explicit interface member implementations
Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio
| C# Language Specification |
|
| © 2006 ECMA International |
20.4.1 Explicit interface member implementations
For purposes of implementing interfaces, a class or struct can declare explicit interface member implementations. An explicit interface member implementation is a method, property, event, or indexer declaration that references a qualified interface member name. [Example:
interface ICloneable { object Clone(); } interface IComparable { int CompareTo(object other); } class ListEntry: ICloneable, IComparable { object ICloneable.Clone() {…} int IComparable.CompareTo(object other) {…} }
Here, ICloneable.Clone and IComparable.CompareTo are explicit interface member
implementations. end example]
[Example: In some cases, the name of an interface member might not be appropriate for the implementing
class, in which case, the interface member can be implemented using explicit interface member
implementation. A class implementing a file abstraction, for example, would likely implement a Close
member function that has the effect of releasing the file resource, and implement the Dispose method of
the IDisposable interface using explicit interface member implementation:
interface IDisposable { void Dispose(); } class MyFile: IDisposable { void IDisposable.Dispose() { Close(); } public void Close() { // Do what's necessary to close the file System.GC.SuppressFinalize(this); } }
end example]
It is not possible to access an explicit interface member implementation through a qualified interface member name in a method invocation, property access, event access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.
It is a compile-time error for an explicit interface member implementation to include any modifiers other than extern (§17.5). It is a compile-time error for an explicit interface method implementation to include type-parameter-constraints-clauses. The constraints for a generic explicit interface method implementation are inherited from the interface method.
Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through a qualified interface member name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public.
Explicit interface member implementations serve two primary purposes:
- 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.
- Explicit interface member implementations allow disambiguation of interface members with the same signature. Without explicit interface member implementations it would be impossible for a class or struct to have different implementations of interface members with the same signature and return type, as would it be impossible for a class or struct to have any implementation at all of interface members with the same signature but with different return types.
For an explicit interface member implementation to be valid, the class or struct shall name an interface in its
base class list that contains a member whose containing type, name, type, number of type parameters, and
parameter types exactly match those of the explicit interface member implementation. If an interface
function member has a parameter array, the corresponding parameter of an associated explicit interface
member implementation is allowed, but not required, to have the params modifier. If the interface function
member does not have a parameter array then an associated explicit interface member implementation shall
not have a parameter array. [Example: Thus, in the following class
class Shape: ICloneable { object ICloneable.Clone() {…} int IComparable.CompareTo(object other) {…} // invalid }
the declaration of IComparable.CompareTo results in a compile-time error because IComparable is not
listed in the base class list of Shape and is not a base interface of ICloneable. Likewise, in the
declarations
class Shape: ICloneable { object ICloneable.Clone() {…} } class Ellipse: Shape { object ICloneable.Clone() {…} // invalid }
the declaration of ICloneable.Clone in Ellipse results in a compile-time error because ICloneable is
not explicitly listed in the base class list of Ellipse. end example]
The qualified interface member name of explicit interface member implementation shall reference the interface in which the member was declared. [Example: Thus, in the declarations
interface IControl { void Paint(); } interface ITextBox: IControl { void SetText(string text); } class TextBox: ITextBox { void IControl.Paint() {…} void ITextBox.SetText(string text) {…} }
the explicit interface member implementation of Paint shall be written as IControl.Paint and not as
ITextBox.Paint. end example]