在 C# 中实现接口与显式实现接口 [重复]

     2023-02-22     30

关键词:

【中文标题】在 C# 中实现接口与显式实现接口 [重复]【英文标题】:Implement Interface vs Implement Interface Explicitly in C# [duplicate] 【发布时间】:2012-03-01 00:29:34 【问题描述】:

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

当我有 IHelper.cs 界面如下:

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

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

    IEnumerable<IPort> IHelper.Ports
    
        get
        
            ...
        
    

而且,“实现接口”给了我这个代码:

    public IEnumerable<IPort> Ports
    
        get
        
            ...
        
    

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

【问题讨论】:

会不会“实现公共接口”和“实现私有接口”太难了? 【参考方案1】:

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

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

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

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

【讨论】:

也(这不是主要原因)当接口发生变化(如方法被删除或更改)时,编译器将在显式定义接口的类上抛出错误,因为这些方法不再存在界面。这是从大型项目中查找未使用代码的有用方法(恕我直言)。 @XenoPuTtSs 好点,我已经修改了我的答案以包含这个。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

更多详情请看article

【讨论】:

最好将文章中的相关信息包含在答案本身中,链接变化无常,可能不会与答案一样长。如果该链接失败,您的回答将无济于事。

c#显式接口成员实现

...;并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。然而,如果两个接口成员实现不同的功能,则可能会导致其中一个接口的实现不正确或两个接口的实... 查看详情

C#接口的隐式和显式实现之间的区别[重复]

】C#接口的隐式和显式实现之间的区别[重复]【英文标题】:DifferencebetweenimplicitandexplicitimplementationofC#interfaces[duplicate]【发布时间】:2010-10-1707:02:39【问题描述】:显式实现接口和实现接口有什么区别。当您从接口派生类时,intel... 查看详情

在 C++/CLI 中实现 C# 接口函数返回数组

】在C++/CLI中实现C#接口函数返回数组【英文标题】:ImplementC#interfacefunctionreturningarray,inC++/CLI【发布时间】:2018-07-1807:19:48【问题描述】:我有一个引用C#dll的C++/CLI项目,我需要实现一个接口类。C#中的接口类是这样的:publicinterf... 查看详情

为啥在具有多个接口() 的对象中实现 QueryInterface() 时我需要显式向上转换

】为啥在具有多个接口()的对象中实现QueryInterface()时我需要显式向上转换【英文标题】:WhyexactlydoIneedanexplicitupcastwhenimplementingQueryInterface()inanobjectwithmultipleinterfaces()为什么在具有多个接口()的对象中实现QueryInterface()时我需要显式... 查看详情

为啥我不能将接口与显式运算符一起使用? [复制]

】为啥我不能将接口与显式运算符一起使用?[复制]【英文标题】:Whycan\'tIuseinterfacewithexplicitoperator?[duplicate]为什么我不能将接口与显式运算符一起使用?[复制]【发布时间】:2011-01-2620:29:08【问题描述】:我只是想知道是否有... 查看详情

C#:在实现的方法中显式指定接口

】C#:在实现的方法中显式指定接口【英文标题】:C#:Explicitlyspecifyingtheinterfaceinanimplementation\'smethod【发布时间】:2010-11-0314:44:47【问题描述】:为什么在实现接口时,如果我将方法设为公开,我不必显式指定接口,但如果我将... 查看详情

如何在 C++ 中实现接口? [复制]

】如何在C++中实现接口?[复制]【英文标题】:howtoimplementInterfacesinC++?[duplicate]【发布时间】:2012-04-0303:42:42【问题描述】:可能重复:PreferredwaytosimulateinterfacesinC++我很想知道C++中是否有接口,因为在Java中,设计模式的实现主要... 查看详情

从泛型基类继承,应用约束,并在 C# 中实现接口

】从泛型基类继承,应用约束,并在C#中实现接口【英文标题】:Inheritfromagenericbaseclass,applyaconstraint,andimplementaninterfaceinC#【发布时间】:2011-01-0117:18:16【问题描述】:这是一个语法问题。我有一个泛型类,它继承自泛型基类,并... 查看详情

区别 b/w 在 C# 中隐式实现成员和显式实现成员 [重复]

...复:C#:Interfaces-ImplicitandExplicitimplementation我正在阅读有关接口重新实现 查看详情

c#接口的隐式和显式实现

1:当类实现一个接口是,通常使用隐式接口实现,这样可以方便的访问接口方法和类自身具有的方法和属性2:当类实现多个接口且接口包含相同的方法签名,此时使用显式接口实现。(标示出哪个接口属于哪个方法)3:隐式接口... 查看详情

了解类型参数是不是在 c# 2.0 中实现接口的更简单方法是啥?

】了解类型参数是不是在c#2.0中实现接口的更简单方法是啥?【英文标题】:Whatistheeasierwaytoknowifatypeparamimplementsaninterfaceinc#2.0?了解类型参数是否在c#2.0中实现接口的更简单方法是什么?【发布时间】:2010-09-1021:29:06【问题描述】... 查看详情

c#图解教程第十五章接口

接口什么是接口使用IComparable接口的示例声明接口实现接口简单接口示例接口是引用类型接口和as运算符实现多个接口实现具有重复成员的接口多个接口的引用派生成员作为实现显式接口成员实现访问显式接口成员实现接口可以... 查看详情

是否可以在 GraphQL 中实现多个接口?

】是否可以在GraphQL中实现多个接口?【英文标题】:IsitpossibletoimplementmultipleinterfacesinGraphQL?【发布时间】:2017-12-2621:30:01【问题描述】:是否可以在GraphQL模式中指定实现多个接口的类型?如果是这样,这将如何实现?【问题讨... 查看详情

在同步对象中实现异步接口

】在同步对象中实现异步接口【英文标题】:ImplementingAsynchronousInterfacesinSynchronousobjects【发布时间】:2018-11-0410:10:05【问题描述】:在学习异步编程时,我一直在尝试实现一个既适用于异步类又适用于同步类的接口,但我看到了... 查看详情

在 C# 中实现 Equals 但不是 GetHashCode [重复]

】在C#中实现Equals但不是GetHashCode[重复]【英文标题】:implementingEqualsbutnotGetHashCodeinc#[duplicate]【发布时间】:2012-05-1721:24:59【问题描述】:可能重复:WhyisitimportanttooverrideGetHashCodewhenEqualsmethodisoverrideninC#?我没有实现Object类的GetHash... 查看详情

C# 中的抽象显式接口实现

】C#中的抽象显式接口实现【英文标题】:abstractexplicitinterfaceimplementationinC#【发布时间】:2010-10-2203:50:59【问题描述】:我有这个C#代码:abstractclassMyList:IEnumerable<T>publicabstractIEnumerator<T>GetEnumerator();//abstractIEnumeratorIEnum 查看详情

扩展三个在Java中实现接口的类

】扩展三个在Java中实现接口的类【英文标题】:ExtendthreeclassesthatimplementsaninterfaceinJava【发布时间】:2021-03-1716:34:50【问题描述】:我使用一个带有接口的库,IFC,它由三个类A、B和C实现。我想自己实现方法M,它在IFC中定义,并... 查看详情

为啥 C# 不允许静态方法实现接口?

...特定行为的接口的类的合同义务。如果类希望在共享方法中实现该行为,为什么不呢?这是我想到的一个例子://Theseitems 查看详情