C# 直接实现一个接口和通过另一个接口实现它之间有什么区别吗?

C# 直接实现一个接口和通过另一个接口实现它之间有什么区别吗?,c#,inheritance,interface,multiple-inheritance,C#,Inheritance,Interface,Multiple Inheritance,也就是说,如果我有接口: public interface Foo { } public interface Bar { } public interface Baz : Foo, Bar { } 我有一个类Qux,如果Qux是这样声明的,是否会有任何代码(除了基于确切接口的反射,或者因为一个版本没有实现Baz而无法工作的东西)会起到不同的作用: public class Qux : Foo, Bar { } 对这个 public class Qux : Baz { } 除了Baz没有

也就是说,如果我有接口:

public interface Foo { }

public interface Bar { }

public interface Baz : Foo, Bar { }
我有一个类
Qux
,如果
Qux
是这样声明的,是否会有任何代码(除了基于确切接口的反射,或者因为一个版本没有实现
Baz
而无法工作的东西)会起到不同的作用:

public class Qux : Foo, Bar { }
对这个

public class Qux : Baz { }

除了
Baz
没有实现的明显差异外,我没有发现其他相关差异

在C#规范中(我正在查看C#4.0第13.4节,但对于较新版本,它仍然应该是正确的),它说:

直接实现接口的类或结构也直接隐式实现接口的所有基接口。即使类或结构没有显式列出基类列表中的所有基类接口,这也是正确的

这意味着以下定义是等效的:

public class Qux : Baz {}
public class Qux : Baz, Foo, Bar {}
它甚至可以让您显式地实现
Foo
接口方法,即使它没有显式地列为基本接口:

public interface Foo { void FooMethod(); }
public interface Bar { void BarMethod(); }
public interface Baz : Foo, Bar { }
public class Qux : Baz
{
    void Foo.FooMethod() { } // legal
    public void BarMethod() { }
}
因此,所有差异应仅与
Baz
接口相关

如果
Baz
是基类而不是接口,则会有差异。第13.4.5节和第13.4.6节规定,除非显式重新实现接口,否则派生类不会更改接口映射。例如:

public interface Foo { string FooMethod(); }
public class Baz : Foo { public string FooMethod() { return "Baz"; } }
public class Qux : Baz { public new string FooMethod() { return "Qux"; } }
Qux
Foo.FooMethod
映射仍然是
Baz.FooMethod

Foo x = new Qux();
x.FooMethod(); // returns "Baz"
但是如果你真的这么做了

public class Qux : Baz, Foo { ... }
。。。它将重新实现接口,并且
x.FooMethod()
将返回“Qux”

值得注意的是,如果你将两者结合起来,例如

public interface Baz : Foo, Bar {}
public class QuxBase : Baz {}
public class Qux : QuxBase, Baz {}
。。。然后,
Qux
仍将起作用,就好像它被定义为
公共类Qux:QuxBase、Baz、Foo、Bar

当一个类实现一个接口时,它还隐式地实现该接口的所有基接口。同样,接口的重新实现也隐含着接口的所有基本接口的重新实现

因此,即使在这种情况下,实现
Baz
和实现
Foo,Bar
之间的唯一区别在于是否实现了
Baz
本身


换句话说,如果您从不使用
Baz
接口本身,我就找不到任何区别。

我认为您在“除外”部分中排除了这两个部分之间几乎所有可能的差异,但没有这样做的意思。你能编辑它来更具体地解释你已经意识到的差异吗?@hvd我知道一个
Qux
没有实现
Baz
,我知道
Type.GetInterfaces()
会有所不同。“功能不同”如何?就接口成员的实现方式而言,这两个选项显然完全不同。在某些方面,这会导致代码实际执行时的不同“功能”。另一方面,接口的整个要点是,可以将对象视为接口,而不是它自己的类型,在这方面,实现从何而来并不重要。第三方面,
Baz
可以很好地实现不同于
Qux
的接口,因此我们再次回到了它们的不同之处。现在还不清楚你在问什么。你的Qux实现和发布的一样好,但只有当Baz为空时,两者才匹配。当然没有人会那样做。术语“接口继承”是坏的。它应该包括“义务”一词。这就是Baz所做的,它赋予实现它的类同样实现Foo和Bar成员的义务。