Implement Interface vs Implement Interface Explicitly in C#
本问题已经有最佳答案,请猛点这里访问。
在VS2010中,我有两个实现接口的选项。
当我有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()); } } |
有关更多详细信息,请参阅本文