在C#中实现接口 vs 显式实现接口 在C#中,实现接口是指一个类可以实现一个或多个接口,并提供接口中定义的所有成员的具体实现。这意味着类必须实现接口中的所有成员,并且可以通过接口的实例引用来访问这些成员。 然而,有时候我们可能需要在类中实现多个接口,并且这些接口中有相同名称的成员。在这种情况下,我们可以使用显式实现接口来解决命名冲突。显式实现接口允许我们在类中实现多个接口,并且可以为每个接口提供不同的实现。 使用显式实现接口时,我们必须在实现的成员之前加上接口名称,以明确指定该成员是属于哪个接口的
在C#中实现接口 vs 显式实现接口 在C#中,实现接口是指一个类可以实现一个或多个接口,并提供接口中定义的所有成员的具体实现。这意味着类必须实现接口中的所有成员,并且可以通过接口的实例引用来访问这些成员。 然而,有时候我们可能需要在类中实现多个接口,并且这些接口中有相同名称的成员。在这种情况下,我们可以使用显式实现接口来解决命名冲突。显式实现接口允许我们在类中实现多个接口,并且可以为每个接口提供不同的实现。 使用显式实现接口时,我们必须在实现的成员之前加上接口名称,以明确指定该成员是属于哪个接口的
在VS2010中,我有两种选项来实现接口。\n当我有以下IHelper.cs接口时:\n
public interface IHelper .... IEnumerablePorts { get; }
\n\"实现接口显式\"给出以下代码:\n
IEnumerableIHelper.Ports { get { ... } }
\n而\"实现接口\"给出以下代码:\n
public IEnumerablePorts { get { ... } }
\n它们是相同的还是不同的?为什么在C#中我有两个选项来实现接口?
在C#中,一个类实现一个接口时可以显式地实现接口的成员。当一个成员被显式实现时,它不能通过类实例访问,只能通过接口实例访问。
这种情况的出现是因为在某些情况下,一个类可能同时需要实现多个接口,并且这些接口可能有相同的成员名称。为了解决这个问题,C#提供了显式接口实现的机制。通过显式实现接口成员,可以为每个接口成员提供单独的实现,避免了命名冲突。
下面的示例展示了如何使用显式接口实现:
// 声明一个接口 interface IDimensions { float Length(); float Width(); } // 实现接口的类 class Box : IDimensions { float lengthInches; float widthInches; // 构造函数 public Box(float length, float width) { lengthInches = length; widthInches = width; } // 显式实现接口成员 float IDimensions.Length() { return lengthInches; } float IDimensions.Width() { return widthInches; } public static void Main() { // 创建类实例 Box myBox = new Box(30.0f, 20.0f); // 创建接口实例 IDimensions myDimensions = (IDimensions)myBox; // 通过接口实例访问接口成员 System.Console.WriteLine("Length: {0}", myDimensions.Length()); System.Console.WriteLine("Width: {0}", myDimensions.Width()); } }
此外,显式接口实现还允许程序员继承具有相同成员名称的两个接口,并为每个接口成员提供单独的实现。下面的示例展示了如何实现一个类,该类继承了两个具有相同成员名称的接口:
// 声明英制单位接口 interface IEnglishDimensions { float Length(); float Width(); } // 声明公制单位接口 interface IMetricDimensions { float Length(); float Width(); } // 实现两个接口的类 class Box : IEnglishDimensions, IMetricDimensions { float lengthInches; float widthInches; // 构造函数 public Box(float length, float width) { lengthInches = length; widthInches = width; } // 显式实现英制单位接口成员 float IEnglishDimensions.Length() { return lengthInches; } float IEnglishDimensions.Width() { return widthInches; } // 显式实现公制单位接口成员 float IMetricDimensions.Length() { return lengthInches * 2.54f; } float IMetricDimensions.Width() { return widthInches * 2.54f; } public static void Main() { // 创建类实例 Box myBox = new Box(30.0f, 20.0f); // 创建接口实例 IEnglishDimensions eDimensions = (IEnglishDimensions)myBox; IMetricDimensions mDimensions = (IMetricDimensions)myBox; // 通过接口实例访问接口成员 System.Console.WriteLine("Length(in): {0}", eDimensions.Length()); System.Console.WriteLine("Width (in): {0}", eDimensions.Width()); System.Console.WriteLine("Length(cm): {0}", mDimensions.Length()); System.Console.WriteLine("Width (cm): {0}", mDimensions.Width()); } }
通过显式接口实现,我们可以为每个接口提供单独的实现,避免了接口成员之间的命名冲突。
更多的细节可以参考这篇文章:[article](http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx)。
在C#中,实现接口有两种方式:隐式实现和显式实现。隐式实现是指将接口成员实现为类的公共成员,而显式实现是指将接口成员实现为接口成员本身。
这两种方式有着明显的区别。如果使用显式实现接口,那么只能通过接口的引用来访问接口的成员。下面的代码示例演示了这个概念:
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); } }
在上面的代码中,`ImplicitFoo`类隐式地实现了`IFoo`接口,因此可以直接通过类的实例访问`Bar`属性。
而`ExplicitFoo`类显式地实现了`IFoo`接口,因此只能通过将类实例强制转换为接口类型来访问`Bar`属性。如果尝试直接访问`expl.Bar`,将会引发编译时异常。
解决这个问题的方法是使用显式实现接口。通过这种方式,可以将接口成员与类的其他成员进行区分,并且只能通过接口的引用来访问接口成员。这在某些特定的情况下非常有用,例如当一个类实现多个接口,并且这些接口具有相同的成员名称时。
总之,隐式实现和显式实现接口在C#中有着不同的用途和行为。开发人员可以根据具体的需求选择适合的实现方式,以实现更灵活和可维护的代码。
实现接口是C#中常见的编程概念之一。在C#中,有两种方式可以实现接口:隐式实现和显式实现。隐式实现是大多数情况下使用的标准方式,它将接口的成员公开在实现类型的公共API上。而显式实现意味着接口的成员仅在接口本身上可用,因此在访问它们之前,实现类型需要将其转换为接口类型。
其中,显式接口定义的主要原因是避免命名冲突,如果你恰巧实现了两个包含相同签名方法的接口,显式定义允许编译器保持足够不同的签名以解决冲突。另一个支持代码维护的次要原因是,显式定义将在实现类型上触发编译器错误,如果方法的签名被删除,则需要手动搜索已废弃的方法实现。
另外,当接口发生变化时(例如删除或更改方法),编译器将在显式定义接口的类上抛出错误,因为这些方法不再存在于接口中。这是一种从大型项目中查找未使用代码的有用方法。
另一个原因是保留可选参数的默认值。
总之,显式实现接口的主要原因是避免命名冲突和支持代码维护,而隐式实现接口是一种常见且简洁的实现方式。根据具体的需求和代码结构,可以选择合适的实现方式。