1

我可以使用显式接口在实现类中隐藏一个方法,如下所示:

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

4 回答 4

1

这是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());
   }
}
于 2013-02-11T13:29:12.150 回答
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

一个更常见的例子是当不可能不这样做时——例如,IEnumerable每个IEnumerable<T>人都有一个GetEnumerator()方法——相同的输入,但不同的返回值。C#不允许通过返回值重载,所以你至少需要两个方法:

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

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

尽管它们也可以都是显式的。或者实际上,在IEnumerator<T>

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

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

class Frobber : IDoSomething {
  public void Frob() {..}
  void IDoSomething.DoIt() { Frob(); }
}
于 2013-02-11T13:31:49.560 回答
0

您可以在这里查看隐式接口和显式接口之间的区别:

C# 接口。隐式实现与显式实现

于 2013-02-11T13:30:09.853 回答
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; } }
}

有人可能会争辩说,这个例子只是接口和数据结构的糟糕设计,但并非总是能够使它们正确,或者完全有能力改变它们。

其他时候,你可能被迫在一个类上实现一些接口,但你真的不希望这些方法对类的用户可见。所有显式实现都被认为是私有的,因此,除非您将对象显式地转换回那个有问题的接口,否则没有人会看到或能够使用这些方法。

于 2013-02-11T13:33:16.973 回答