在 C# 中实现接口与显式实现接口

发布于 2025-01-04 00:45:02 字数 583 浏览 2 评论 0原文

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

在此处输入图像描述

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

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

“显式实现接口”给出以下代码:

    IEnumerable<IPort> IHelper.Ports
    {
        get
        {
            ...
        }
    }

并且,“实现接口”给了我这段代码:

    public IEnumerable<IPort> Ports
    {
        get
        {
            ...
        }
    }

它们是相同还是不同?为什么在 C# 中实现接口有两种选择?

I have two options in VS2010 for implementing interfaces.

enter image description here

When I have IHelper.cs interface as follows:

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

"Implement Interface Explicitly" gives this code:

    IEnumerable<IPort> IHelper.Ports
    {
        get
        {
            ...
        }
    }

And, "Implement Interface" gives me this code:

    public IEnumerable<IPort> Ports
    {
        get
        {
            ...
        }
    }

Are they the same or different? Why do I have two options in implementing interfaces in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

厌倦 2025-01-11 00:45:02

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

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

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

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

Explicit interface declarations mean that the interface members are not available on types other than the interface itself, so implementing types would need to be cast to the interface before accessing them publicly.

Implicit, the standard way in which most interfaces are implemented, exposes interface items on the implementor-type's public API.

The main reason for explicit interface definitions is to avoid naming conflicts if you happen to implement two interfaces that contain methods with the same signature... the explicit definition allows the compiler to keep the signatures distinct enough to resolve.

A secondary reason that supports code maintenance, as suggested by XenoPuTtSs in the comments, is that explicit definitions will trigger compiler errors on the implementing types if the method signature is removed. On implicit implementations, removing a method from the interface will leave the method as a regular member of any types - meaning you need to search manually for now-defunct method implementations.

一个人的旅程 2025-01-11 00:45:02

他们是完全不同的。如果显式实现接口,您将只能通过引用该接口来引用接口成员。下面的代码演示了这个想法。

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

They are totally different. If you implement interfaces explicitely you'll be able to reference the interface members only by reference of that interface. The following code demonstrates the idea.

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);
    }
}
夏日浅笑〃 2025-01-11 00:45:02

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

// 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,分别代表不同的测量系统。两个接口具有相同的成员名称、长度和宽度。

查看示例

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

以了解更多详细信息,请查看此文章

A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.

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

Explicit interface implementation also allows the programmer to inherit two interfaces that share the same member names and give each interface member a separate implementation. This example displays the dimensions of a box in both metric and English units. The Box class inherits two interfaces IEnglishDimensions and IMetricDimensions, which represent the different measurement systems. Both interfaces have identical member names, Length and Width.

look at the example

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

for more details look at this article

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文