关于visual studio:在C#中明确实现接口与实现接口

Implement Interface vs Implement Interface Explicitly in C#

本问题已经有最佳答案,请猛点这里访问。

在VS2010中,我有两个实现接口的选项。

enter image description here

当我有ihelper.cs接口时,如下所示:

1
2
3
public interface IHelper
    ....
    IEnumerable<IPort> Ports { get; }

"显式实现接口"给出了以下代码:

1
2
3
4
5
6
7
    IEnumerable<IPort> IHelper.Ports
    {
        get
        {
            ...
        }
    }

"实现接口"给出了以下代码:

1
2
3
4
5
6
7
    public IEnumerable<IPort> Ports
    {
        get
        {
            ...
        }
    }

它们是相同的还是不同的?为什么在C中实现接口有两个选项?


显式接口声明意味着接口成员在接口本身之外的类型上不可用,因此在公开访问类型之前,需要将实现类型强制转换为接口。

隐式是实现大多数接口的标准方式,它公开实现者类型的公共API上的接口项。

显式接口定义的主要原因是为了避免命名冲突,如果您碰巧实现了两个包含具有相同签名的方法的接口…显式定义允许编译器将签名保持足够的不同以进行解析。

正如Xenoputts在注释中所建议的,支持代码维护的第二个原因是,如果移除方法签名,显式定义将触发实现类型上的编译器错误。在隐式实现中,从接口中删除一个方法将使该方法成为任何类型的常规成员——这意味着您需要手动搜索现在已失效的方法实现。


它们完全不同。如果您明确地实现接口,那么您将只能通过引用该接口来引用接口成员。下面的代码演示了这个想法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public interface IFoo {
    String Bar { get; set; }
}
public class ImplicitFoo : IFoo {
    public string Bar {get;set;}
}
public class ExplicitFoo : IFoo {
    private String _Bar;
    string IFoo.Bar {
        get {
            return _Bar;
        }
        set {
            _Bar = value;
        }
    }
}
public class Test {
    public void Test() {
        var iml = new ImplicitFoo();
        // Works fine
        Console.WriteLine(iml.Bar);
        var expl = new ExplicitFoo();
        var fooInterface = (IFoo)expl;
        // Works fine
        Console.WriteLine(fooInterface.Bar);
        // Throws compile time exception
        Console.WriteLine(expl.Bar);
    }
}


实现接口的类可以显式实现该接口的成员。当成员显式实现时,不能通过类实例访问它,只能通过接口的实例访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 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());
 }
}

显式接口实现还允许程序员继承共享相同成员名称的两个接口,并为每个接口成员提供单独的实现。此示例以公制和英制单位显示框的尺寸。Box类继承了两个接口IEnglishDimensions和IMetricDimensions,它们代表不同的度量系统。两个接口具有相同的成员名称、长度和宽度。

看看这个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// 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());
 }
}

有关更多详细信息,请参阅本文