C# 在两个不同接口的两个方法中使用相同的名称,为什么不使用一个实现?

C# 在两个不同接口的两个方法中使用相同的名称,为什么不使用一个实现?,c#,interface,C#,Interface,如果我有两个同名但返回类型不同的方法。它们由一个类从2个接口继承。如果实现的返回类型符合两个接口中的返回类型,则此类可以为这两个接口提供1个实现 例如,Stringtype实现了两种方法:IEnumerable和IEnumerable。String类型的实现只包含一个GetEnumerator的实现 public CharEnumerator GetEnumerator(); 我相信这是可能的,因为CharEnumerator实现了IEnumerator和IEnumerator 公共字符枚举器

如果我有两个同名但返回类型不同的方法。它们由一个类从2个接口继承。如果实现的返回类型符合两个接口中的返回类型,则此类可以为这两个接口提供1个实现

例如,
String
type实现了两种方法:
IEnumerable
IEnumerable
String
类型的实现只包含一个
GetEnumerator
的实现

public CharEnumerator GetEnumerator();
我相信这是可能的,因为
CharEnumerator
实现了
IEnumerator
IEnumerator

公共字符枚举器:IEnumerator,IEnumerator
但是,下面我的应用程序中的类似代码给了我一个编译错误

interface Ia { IEnumerator o();}
interface Ib { IEnumerator<int> o();}
class e : IEnumerator, IEnumerator<int>{}
class c : Ia, Ib { public e o() { return new e(); } }
接口Ia{IEnumerator o();}
接口Ib{IEnumerator o();}
e类:IEnumerator,IEnumerator{}
类c:Ia,Ib{public e o(){return new e();}
如果我在Visual Studio中对字符串类型执行F12操作,我会看到如下所示,

如您所见,只有一个
GetEnumerator()
的隐式实现,没有显式实现

字符串不会隐式实现
IEnumerable
IEnumerable
。它显式地这样做,这意味着您只能通过
IEnumerable
IEnumerable
引用来访问这些方法

方法
CharEnumerator GetEnumerator()
既不实现任何接口,因为返回类型不是
IEnumerator
IEnumerator
CharEnumerator
是一种可能的
IEnumerator
,但接口要求任何
IEnumerator

显式接口非常有用,您刚刚偶然发现了它们提供的一个特性;在一个类中实现定义同名方法的不同接口:

interface IFoo
{
    IFoo Frob();
}

interface IBar
{
    IBar Frob();
}

public class Blah: IFoo, IBar
{
    Foo IFoo.Frob() => new Foo();
    Bar IBar.Frob() => new Bar();
    void Frob();
}
现在,您将获得以下行为:

var b = new Blah();
b.Frob(); //returns nothing, this method is not implementing any of the two interfaces.
(b as IBar).Frob(); //returns a bar
(b as IFoo).Frob(); //returns a foo

C语言不支持返回类型协方差。这就是为什么String类有两个GetEnumerator()方法。第二种是一种明确的实现方法,这是避免歧义的必要条件。以及为什么还需要两个接口。@HansPassant我认为这两个接口都是显式实现的
string.GetEnumerator
实际上返回一个
CharEnumerator
,它不符合两个接口约定中的任何一个。我猜这是C语言的遗留代码#1@HansPassant那么为什么我的代码无法编译,类型
e
确实来自
IEnumerable
以及
IEnumerable
您是对的。他们试图清除.NETCore中的CharEnumerator。请参阅上面编辑的问题。VisualStudio仅显示GetEnumerator()@EartoLearn No的一个隐式实现,它不是隐式实现
CharEnumerator GetEnumerator()
不实现任何接口。请参阅对我的示例的编辑,以查看类似情况。检查类型定义时不显示显式实现。明白了。因此,string除了提供两个显式实现之外,还提供了
CharEnumerator GetEnumerator()
,分别用于
IEnumerable
IEnumerable
。但是为什么不简单地让
IEnumerable.GetEnumerator()
显式,让
IEnumerable.GetEnumerator()
可用呢?@渴望学习,因为
string
从第一天起就在框架中,迭代器和泛型随后就进入了该语言。谢谢。这澄清了所有问题。String类的MSDN页面显示了类型上的1个GetEnumerator()方法和2个显式方法实现。
var b = new Blah();
b.Frob(); //returns nothing, this method is not implementing any of the two interfaces.
(b as IBar).Frob(); //returns a bar
(b as IFoo).Frob(); //returns a foo