在C#中使用显式接口

时间:2013-02-11 13:25:47

标签: c# oop interface

我可以使用显式接口隐藏实现类中的方法:

interface IInterface
{
    void f1();

}
public class C1 : IInterface
{
    void IInterface.f1()
    {
        Console.WriteLine(" Method Called ....");
    }

}

然后可以访问该方法:

C1 C = new C1();
IInterface i = C;
i.f1();

方法f1将从实现类C1中隐藏。这种功能的目的是什么?任何人都可以为我提供真实的生活场景吗?

4 个答案:

答案 0 :(得分:1)

有些情况下,您不希望以直接形式在公共API上公开某些内容。也许它从不工作;也许公共API可以公开相同功能的更合适的签名。例如:

public int Add(Foo foo) {...} // takes a known type and returns the new index
void ICollection.Add(object obj) {...} // takes object and returns void

一个更常见的例子是不可能不能 - 例如,IEnumerableIEnumerable<T>每个都有GetEnumerator()方法 - 相同的输入,但是回报值不同。 C#不允许通过返回值进行重载,因此您至少需要两种方法:

IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }

public IEnumerator<T> GetEnumerator() { ...}

虽然它们也可以是明确的。或者确实,在IEnumerator<T>

public T Current { get { ... } }
object IEnumerator.Current { get { return Current; } }

此外,有时您只想重命名。例如,出于某种原因,Frobber的方法自然为Frob()。但它也实现了IDoSomething接口,该接口具有DoIt()方法;您现在可以使API反映出表达意图的最合适的术语:

class Frobber : IDoSomething {
  public void Frob() {..}
  void IDoSomething.DoIt() { Frob(); }
}

答案 1 :(得分:0)

以下是MSDN的一个很好的例子,它帮助我理解了为什么它们可以提供帮助:

此示例以公制和英制单位显示框的尺寸。 Box类继承了两个接口IEnglishDimensions和IMetricDimensions,它们代表不同的测量系统。两个接口都具有相同的成员名称,长度和宽度。

// 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());
   }
}

答案 2 :(得分:0)

您可以在此处查看隐式和显式界面之间的区别:

C# Interfaces. Implicit implementation versus Explicit implementation

答案 3 :(得分:0)

其中一个真实场景是方法名称冲突。想象:

interface IWarehouseItem
{
    string Name {get;} // the NAME of the PRODUCT
    int Count {get;}
    int PricePerUnit {get;}
}

interface IWarehouseSupplierInformation
{
    string Name {get;} // the NAME of the SUPPLIER
    int ID {get;}
    int IDAddress {get;}
}

class PurchaseableItem : Entity, IWarehouseItem, IWarehouseSupplierInformation
{
    ....
    // how to implement those different names?
     ....
    string IWarehouseItem.Name { get { this.Product.Name; } }
    ...
    string IWarehouseSupplierInformation.Name { get { this.Supplier.Name; } }
}

有人可能会争辩说,这个例子只是界面和数据结构的糟糕设计,但并不总是你能够使它们正确,或者根本无法改变它们。

其他时候,您可能被迫在类上实现某个接口,但实际上您真的不希望这些方法对类的用户可见。 所有显式实现都被视为私有,因此,除非您明确地将对象强制转换回有问题的界面,否则任何人都无法看到或能够使用这些方法。