disable broken tests on net_4_0
[mcs.git] / docs / ecma334 / 20.4.1.xml
blob39ed663e073099a578aec3894b5353b36be66675
1 <?xml version="1.0"?>
2 <clause number="20.4.1" title="Explicit interface member implementations">
3   <paragraph>For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. <example>[Example: For example <code_example><![CDATA[
4 interface ICloneable  
5 {  
6    object Clone();  
7 }  
8 interface IComparable  
9 {  
10    int CompareTo(object other);  
11 }  
12 class ListEntry: ICloneable, IComparable  
13 {  
14    object ICloneable.Clone() {...}  
15    int IComparable.CompareTo(object other) {...}  
16 }  
17 ]]></code_example></example></paragraph>
18   <paragraph>
19     <example>Here, ICloneable.Clone and IComparable.CompareTo are explicit interface member implementations. end example]</example>
20   </paragraph>
21   <paragraph>
22     <example>[Example: In some cases, the name of an interface member may not be appropriate for the implementing class, in which case the interface member may 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: <code_example><![CDATA[
23 interface IDisposable {  
24    void Dispose();  
25 }  
26 class MyFile: IDisposable {  
27    void IDisposable.Dispose() {  
28       Close();  
29    }  
30    public void Close() {  
31       // Do what's necessary to close the file  
32       System.GC.SuppressFinalize(this);  
33    }  
34 }  
35 ]]></code_example>end example]</example>
36   </paragraph>
37   <paragraph>It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property 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. </paragraph>
38   <paragraph>It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static. </paragraph>
39   <paragraph>Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through their fully qualified 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. </paragraph>
40   <paragraph>Explicit interface member implementations serve two primary purposes: <list><list_item> 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. </list_item><list_item> 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. </list_item></list></paragraph>
41   <paragraph>For an explicit interface member implementation to be valid, the class or struct must name an interface in its base class list that contains a member whose fully qualified name, type, and parameter types exactly match those of the explicit interface member implementation. <example>[Example: Thus, in the following class <code_example><![CDATA[
42 class Shape: ICloneable  
43 {  
44    object ICloneable.Clone() {...}  
45    int IComparable.CompareTo(object other) {...}  // invalid  
46 }  
47 ]]></code_example>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 <code_example><![CDATA[
48 class Shape: ICloneable  
49 {  
50    object ICloneable.Clone() {...}  
51 }  
52 class Ellipse: Shape  
53 {  
54    object ICloneable.Clone() {...} // invalid  
55 }  
56 ]]></code_example>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]</example> </paragraph>
57   <paragraph>The fully qualified name of an interface member must reference the interface in which the member was declared. <example>[Example: Thus, in the declarations <code_example><![CDATA[
58 interface IControl  
59 {  
60    void Paint();  
61 }  
62 interface ITextBox: IControl  
63 {  
64    void SetText(string text);  
65 }  
66 class TextBox: ITextBox  
67 {  
68    void IControl.Paint() {...}  
69    void ITextBox.SetText(string text) {...}  
70 }  
71 ]]></code_example>the explicit interface member implementation of Paint must be written as IControl.Paint. end example]</example> </paragraph>
72 </clause>