Explizite Schnittstellenimplementierungen

In diesem Lernprogramm wird erläutert, wie Schnittstellenmember explizit implementiert werden und wie über die Schnittstelleninstanzen auf diese Member zugegriffen wird.

Weitere Themen

Lernprogramm

Eine Klasse, die eine Schnittstelle implementiert, ist in der Lage, ein Member dieser Schnittstelle explizit zu implementieren. Bei der expliziten Implementierung eines Members kann nicht über eine Klasseninstanz, sondern lediglich über eine Instanz der Schnittstelle darauf zugegriffen werden. Dieses Lernprogramm umfasst zwei Beispiele. Im ersten Beispiel wird die explizite Implementierung und der explizite Zugriff auf Schnittstellenmember veranschaulicht. Das zweite Beispiel verdeutlicht, wie zwei Schnittstellen mit identischen Membernamen implementiert werden.

Beispiel 1

In diesem Beispiel werden die IDimensions-Schnittstelle sowie die Box-Klasse deklariert, durch die die Schnittstellenmember Length und Width explizit implementiert werden. Für den Zugriff auf die Member wird die myDimensions-Schnittstelleninstanz verwendet.

// explicit1.cs
interface IDimensions 
{
   float Length();
   float Width();
}

class Box : IDimensions 
{
   float lengthInches;
   float widthInches;

   public Box(float length, float width) 
   {
      lengthInches = length;
      widthInches = width;
   }
   // Explicit interface member implementation: 
   float IDimensions.Length() 
   {
      return lengthInches;
   }
   // Explicit interface member implementation:
   float IDimensions.Width() 
   {
      return widthInches;      
   }

   public static void Main() 
   {
      // Declare a class instance "myBox":
      Box myBox = new Box(30.0f, 20.0f);
      // Declare an interface instance "myDimensions":
      IDimensions myDimensions = (IDimensions) myBox;
      // Print out the dimensions of the box:
      /* The following commented lines would produce compilation 
         errors because they try to access an explicitly implemented
         interface member from a class instance:                   */
      //System.Console.WriteLine("Length: {0}", myBox.Length());
      //System.Console.WriteLine("Width: {0}", myBox.Width());
      /* Print out the dimensions of the box by calling the methods 
         from an instance of the interface:                         */
      System.Console.WriteLine("Length: {0}", myDimensions.Length());
      System.Console.WriteLine("Width: {0}", myDimensions.Width());
   }
}
Ausgabe
Length: 30
Width: 20

Codeerläuterung

Beispiel 2

Bei der expliziten Schnittstellenimplementierung hat der Entwickler zusätzlich die Möglichkeit, mittels Vererbung zwei Schnittstellen zu verwenden, die über identische Membernamen verfügen, und jeden Schnittstellenmember getrennt zu implementieren. In diesem Beispiel werden die Abmessungen eines Feldes sowohl in metrischen als auch in englischen Maßeinheiten ausgegeben. Die Box-Klasse erbt die beiden Schnittstellen IEnglishDimensions und IMetricDimensions, die die unterschiedlichen Bemaßungssysteme darstellen. Beide Schnittstellen verfügen über identische Membernamen:Length und Width.

// explicit2.cs
// Declare the English units interface:
interface IEnglishDimensions 
{
   float Length();
   float Width();
}
// Declare the metric units interface:
interface IMetricDimensions 
{
   float Length();
   float Width();
}
// Declare the "Box" class that implements the two interfaces:
// IEnglishDimensions and IMetricDimensions:
class Box : IEnglishDimensions, IMetricDimensions 
{
   float lengthInches;
   float widthInches;
   public Box(float length, float width) 
   {
      lengthInches = length;
      widthInches = width;
   }
// Explicitly implement the members of IEnglishDimensions:
   float IEnglishDimensions.Length() 
   {
      return lengthInches;
   }
   float IEnglishDimensions.Width() 
   {
      return widthInches;      
   }
// Explicitly implement the members of IMetricDimensions:
   float IMetricDimensions.Length() 
   {
      return lengthInches * 2.54f;
   }
   float IMetricDimensions.Width() 
   {
      return widthInches * 2.54f;
   }
   public static void Main() 
   {
      // Declare a class instance "myBox":
      Box myBox = new Box(30.0f, 20.0f);
      // Declare an instance of the English units interface:
      IEnglishDimensions eDimensions = (IEnglishDimensions) myBox;
      // Declare an instance of the metric units interface:
      IMetricDimensions mDimensions = (IMetricDimensions) myBox;
      // Print dimensions in English units:
      System.Console.WriteLine("Length(in): {0}", eDimensions.Length());
      System.Console.WriteLine("Width (in): {0}", eDimensions.Width());
      // Print dimensions in metric units:
      System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
      System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());
   }
}

Ausgabe

Length(in): 30
Width (in): 20
Length(cm): 76.2
Width (cm): 50.8

Codeerläuterung

Wenn die englischen Maßeinheiten als Standard verwendet werden sollen, implementieren Sie die Methoden Length und Width auf normale Weise und die Methoden Length und Width aus der IMetricDimensions-Schnittstelle explizit:

// Normal implementation:
public float Length()
{
   return lengthInches;
}
public float Width()
{
   return widthInches;
}
// Explicit implementation:
float IMetricDimensions.Length() 
{
   return lengthInches * 2.54f;
}
float IMetricDimensions.Width() 
{
   return widthInches * 2.54f;
}

In diesem Fall kann über die Klasseninstanz auf die englischen Maßeinheiten und über die Schnittstelleninstanz auf die metrischen Einheiten zugegriffen werden:

System.Console.WriteLine("Length(in): {0}", myBox.Length());
System.Console.WriteLine("Width (in): {0}", myBox.Width());   
System.Console.WriteLine("Length(cm): {0}", mDimensions.Length());
System.Console.WriteLine("Width (cm): {0}", mDimensions.Width());