首页 文章

为什么C#泛型不能像C模板中那样从泛型类型参数中派生出来? [重复]

提问于
浏览
42

这个问题在这里已有答案:

为什么C#泛型不能像C模板中那样从泛型类型参数中派生出来?我的意思是我知道这是不可能的,因为CLR不支持这个,但为什么呢?

我知道C模板和C#泛型之间的深刻差异 - 前者是编译时实体,必须在编译期间解析,而后者是一流的运行时实体 .

尽管如此,我还是没有看到为什么CLR设计者没有提出一种方案,这种方案最终会使CLR泛型类型从其泛型类型参数中派生出来 . 毕竟,这将是非常有用的功能,我个人非常想念它 .

EDIT:

我想知道一个核心问题,解决这个问题会产生如此高的代价来实现这个功能,这个功能证明它还没有得到实施 . 例如,检查这个虚构的声明:

class C<T> : T
{
}

正如Eric Lippert已经注意到如果“ What if T is a struct? What if T is a sealed class type? What if T is an interface type? What if T is C?! What if T is a class dervied from C? What if T is an abstract type with an abstract method? What if T has less accessibility than C ? What if T is System.ValueType? (Can you have a non-struct which inherits from System.ValueType?) What about System.Delegate, System.Enum, and so on?

埃里克继续说,“ Those are the easy, obvious ones ” . 的确,他是对的 . 我感兴趣的是一个既不容易也不明显的问题的具体例子,这个问题很难解决 .

5 回答

  • 1

    好吧,首先问问自己 class C<T> : T { } 可能出现什么问题 . 马上就会想到很多东西:

    如果T是结构怎么办?如果T是密封类型怎么办?如果T是接口类型怎么办?如果T是 C<T> 怎么办?如果T是从 C<T> 派生的类怎么办?如果T是带抽象方法的抽象类型怎么办?如果T的可访问性低于C,该怎么办?如果T是System.ValueType怎么办? (你有一个从System.ValueType继承的非结构吗?)System.Delegate,System.Enum等等怎么样?

    这些是简单明了的 . 所提出的特征打开了数百个,如果不是数千个关于类型与其基类型之间的相互作用的更微妙的问题,所有这些都必须仔细指定,实施和测试 . 毫无疑问,我们会错过一些,从而导致未来发生重大变化,或者通过实现定义的行为来限制运行时 .

    成本将是巨大的,因此效益最好是巨大的 . 我没有看到这里的巨大好处 .

  • 2

    好吧,如果你不喜欢我以前的答案,那么让我们采取不同的策略 .

    你的问题预示着虚假:我们需要一个不实现功能的理由 . 相反,我们需要一个非常非常好的理由来实现任何功能 . 它们的前期成本,维护成本和机会成本非常昂贵 . (也就是说,您在功能X上花费的时间是您不能花费在功能Y上的时间,这可能会阻止您使用功能Z.)为了负责任地为我们的客户和利益相关者提供 Value ,我们无法实现每项功能有人碰巧喜欢 .

    运行时设计师无法证明为什么他们没有实现您觉得特别好的功能 . 根据成本与用户的利益优先考虑功能,用户并没有完全按照我的要求进行这种继承 . 这个特殊的功能将大大改变类型系统的分析在运行时的工作方式,对消耗泛型的每种语言都有深远的影响,而且在我看来提供的好处很少 .

    我们在编译器中使用这种继承 - 用C语言编写 - 并且生成的代码很难遵循,难以维护,并且难以调试 . 我一直在尽力逐步消除这样的代码 . 我反对在C#中启用相同类型的错误模式,除非这样做有非常令人信服的好处 .

    以令人信服的方式描述这种巨大利益的任务是针对想要该功能的人,而不是那些必须实现它的人 . 那么有什么吸引人的好处呢?

  • 11

    代码示例,这可能会有所帮助:

    public class SpecialDataRow<T> : T where T : DataRow
    {
        public int SpecialFactor { get; set; }
    }
    

    这样就可以从DataRow和任何派生的DataRows(如类型化生成的数据集)中创建“特殊”行 .

    我没有看到任何其他方式如何编写这样的类

  • 62

    什么对此有用?

    请记住,尽管名称,泛型从未打算支持泛型编程 .

    为了支持这样的功能,他们必须做一些漂亮的CLR的戏剧性变化 .

    您需要定义一个派生自编译时甚至不存在的类的类 .

    他们为什么要跳过这样的环节并且从根本上妥协他们的类型系统只是为了添加这个功能?这值得么?

    如果您这么认为,请告诉他们原因 . 在connect.microsoft.com上写下反馈,告诉他们为什么这个功能如此基础以至于必须添加它 .

  • 34

    C模板无法与C#泛型进行比较 . C模板像宏一样进行预处理,而.NET中的泛型则由运行时处理 .

    但还有其他人比我更了解这一点......

相关问题