为什么C#允许通过接口扩展方法而不是类来进行多重继承? [英] Why does C# allow multiple inheritance though interface extension methods but not classes?

查看:185
本文介绍了为什么C#允许通过接口扩展方法而不是类来进行多重继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经检查了其他问题,但令人惊讶的是,似乎没有问过这个问题。使用Extension方法,接口提供有限但真正的实现多重继承。这带来了Diamond问题,与基于类的多继承相同。为什么这比基于类的多重继承更好或更可接受,这么多人似乎觉得这么可怕?它实际上似乎是实现多重继承的一种更糟糕的方式,因为扩展方法不能进入接口本身,甚至不能进入实现接口的类,但最终可能分散在多个静态实用程序类中。

I've checked through other questions and surprisingly this question doesn't seem to have been asked. With Extension methods, interfaces provide limited but true implementation multiple inheritance. This brings with it the Diamond problem, the same as with class based multiple inheritance. Why is this better or more acceptable than class based multiple inheritance that so many people seem to find so horrifying? It actually seems a much worse way of implementing multiple inheritance as extension methods can't go in the interface itself or even a class that implements the interface but can end up scattered over multiple static utility classes.

Eric Lippert在他的博客(2009年10月5日上午9:29)似乎对扩展属性的想法持开放态度,甚至提到了扩展事件,扩展操作符,扩展构造函数(也称为工厂模式)的可能性)。因此,可以进一步扩展通过接口的实现。

Eric Lippert in his blog (5 Oct 2009 9:29 AM) seemed open to the idea of extension properties and even mentions the possibility of extension events, extension operators, extension constructors (also known as "the factory pattern"). So implementation through interfaces could be further extended.

编辑:为了澄清一个类是否从两个接口都继承了两个接口的扩展方法相同的名称和类型参数,如果在没有明确命名接口的情况下调用方法,它将产生编译错误。考虑到这一点,我错了,因为这不是钻石问题。然而,考虑到这一点提出了一个问题,即钻石问题与其他歧义相比有多重要?为什么Diamond问题难以解决,它是否可以通过简单的编译错误来获取,就像接口扩展方法类碰撞并且不能隐式解析一样?即使在基于类的多重继承中,也可能存在非基于Diamond的成员签名冲突。

To clarify if a class inherits from two interfaces that both have an extension method of the same name and type parameters then it will produce a compile error if a method is called with out explicitly naming the interface. Having thought about this I was mistaken as this is not the Diamond problem. However thinking about this raises the question of what is so important about the Diamond problem as opposed to other ambiguities? Why is the Diamond problem such a difficulty, that it can it not be picked up with a simple compile error the same as when interface extension methods class clash and are not implicitly resolvable? Even within class based multiple inheritance it is possible to have member signature clashes that are not Diamond based.

推荐答案


使用扩展方法,接口提供有限但真正的实现多重继承。

With extension methods, interfaces provide limited but true implementation multiple inheritance.

这句话是整个问题的基础,但我无法做出头脑或尾巴,因此很难回答问题。

This sentence is the basis for the entire question but I cannot make heads nor tails of it, so it will be difficult to answer the question.

首先,让我们明确定义继承。当我们说类型D继承自类型B时,我们的意思是 B的每个成员也是D†的成员。那是全部,我们的意思是C#中的继承。

First off, let's clearly define "inheritance". When we say that a type D inherits from a type B, what we mean is that every member of B is also a member of D†. That is all that we mean by "inheritance" in C#.

类(或结构)从一个(††)基类继承成员。一个类可以实现任意数量的接口;这与基类继承完全不同。类不需要具有与其实现的接口相同的成员集合,因为该类可以使用显式接口实现来提供实现而不需要成员班上。显式接口实现只能通过接口访问,并且不能以任何其他方式访问,因此将它视为从接口继承的类的成员会很奇怪。

A class (or struct) inherits members from exactly one(††) base class. A class may implement any number of interfaces; this is quite different from base class inheritance. A class is not required to have the same set of members that an interface it implements has, because the class can use explicit interface implementation to provide an implementation without making a member of the class. The explicit interface implementation is only accessible via the interface, and cannot be accessed in any other way, so it would be strange to think of it as a "member" of the class that is "inherited" from the interface.

接口从任意数量的其他接口继承成员。从技术上讲,这可以被认为是继承;基接口的成员是派生接口的成员。但是我希望我们没有在规范中描述它;我认为说接口不从基接口继承会更清楚;相反,一个接口可以要求实现其他接口作为合同的一部分。

An interface "inherits" members from any number of other interfaces. And technically, this can be thought of as inheritance; members of the base interfaces are members of the derived interface. But I wish that we had not described it like that in the specification; I think it would have been more clear to say that interfaces do not inherit from base interfaces; rather, an interface can require the implementation of other interfaces as part of its contract.

现在我们已经解决了这个问题。那么扩展方法呢?扩展方法不是任何类型的继承;扩展的类型不会获得任何新成员。扩展方法只是一种更愉快地编写静态方法调用的方法。

Now that we've got that out of the way, what about extension methods? Extension methods are not any kind of inheritance; the type that is extended does not get any new members. Extension methods are rather just a way to more pleasantly write a call to a static method.


这带来了Diamond问题,与基于类的多重继承相同

This brings with it the Diamond problem, the same as with class based multiple inheritance

目前还不清楚该句中this是指什么。你指的是(1)实现多个接口的类,(2)从多个接口继承的接口,或者(3)关于扩展方法的东西,或者(4)完全不同的东西?我不明白钻石问题与你的问题有什么关系。你能澄清一下吗?

It is unclear what "this" refers to in that sentence. Are you referring to (1) classes implementing multiple interfaces, (2) interfaces inheriting from multiple interfaces, or (3) something about extension methods, or (4) something else entirely? I do not understand what the diamond problem has to do with your question. Can you clarify it?


为什么这比基于类的多重继承更好或更可接受,这么多人似乎觉得这么可怕? / p>

Why is this better or more acceptable than class based multiple inheritance that so many people seem to find so horrifying?

为什么更好

I我根本不理解这个问题,但似乎在某处有某种有用的问题。你能澄清一下这个问题吗?最好用一些简短的示例代码来演示你正在谈论的内容。

I'm not understanding this question at all but it seems like there is some kind of useful question in here somewhere. Can you clarify the question? Preferably with some short, simple example code that demonstrates what you're talking about.

†不是每个成员。例如,构造函数和析构函数是成员,但不是可继承的成员。私有成员 继承,但可能无法通过名称​​访问

† Not every member. Constructors and destructors for example are members, but are not inheritable members. Private members are inherited but might not be accessible by name.

†† object ,它继承自零类。每个其他类都只从一个类继承。

†† Except for object, which inherits from zero classes. Every other class inherits from exactly one class.

这篇关于为什么C#允许通过接口扩展方法而不是类来进行多重继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆