c# - 在c#中允许重写扩展会有什么问题

标签 c# oop extension-methods

根据语言规范 http://msdn.microsoft.com/en-us/library/bb383977.aspx

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.

我不明白的是为什么有这个限制? 允许覆盖扩展会有哪些编程问题?

一个简单的案例研究

基类 Object 有一个方法 ToString(),它默认将对象类型名称返回为字符串。可以说,出于所有意图和目的,它旨在被覆盖。

默认情况下,Stream 不提供对 ToString 的覆盖,因为它不知道将字节转换为字符串是否有意义。

但是,作为解决方案的程序员,我知道如果转换为字符串,所有流都是有意义的。但是,我不想,或者不能,从流类派生。因此,我想扩展 ToString 方法以将流转换为字符串;像这样:

public static String ToString(this Stream stream)
{
    var memory = new MemoryStream(); //closable
    var reader = new StreamReader(memory);
    stream.Position = 0;
    stream.CopyTo(memory);
    memory.Position = 0;
    return reader.ReadToEnd();
}

但是,根据规范,这永远不会在运行时调用。但为什么在这种情况下限制如此严格?由于 Stream 派生自 Object,这难道不意味着任何专门用于 Stream 的扩展方法都应该默认覆盖基类型方法吗?

此外,在某些情况下,简单地将其命名为 AsString 是没有用的;即 WPF,它使用 ToString 作为后备来表示一个项目。

最佳答案

扩展方法在扩展对象的继承层次之外。

语言(和 IDE)只是让这个完全独立类看起来像是扩展类型的一部分。

为了允许覆盖,整个继承模型和扩展机制需要改变——这是一个非常大的改变,可能是一个突破性的改变。

简而言之 - 这是一项实现成本超过其实用性的功能。

关于c# - 在c#中允许重写扩展会有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15247466/

相关文章:

c# - 如何为类型创建扩展方法

swift - 在 swift 3 中使用扩展时使用未解析的标识符

c# - 如何在 Windows 文本框中将字符串转换为大写?

c# - 具有最近邻过滤图像裁剪边缘的winforms图形

c# - 如何仅导入类型而不导入实例?

c# - 在 windows azure 上找不到路径的一部分

javascript - 使用ES6类扩展错误

java - 将参数传递给对象数组

c# - 在c#中声明一个可以是任何类型的对象

c# - 如何使[示例]扩展方法更加通用/实用/高效?