为什么元组<t1,t2,t3>不从元组继承<t1,t2>?</t1,t2> </t1,t2,t3>

时间:2014-05-04 15:46:39

标签: c# c#-4.0 tuples

自C#4.0起,Tuple类可用。为什么具有三个元素的Tuple不是具有两个元素的Tuple的子类?

这在定义适用于任何元组的操作First : Tuple<T1,T2> -> T1时非常有用,无论其他项目的数量是多少。

此外,由于元组的元素是只读的,为什么Tuple<T1,T2>不是协变的? (例如,ITuple<Foo,Bar>也是ITuple<SuperFoo,SuperBar>

2 个答案:

答案 0 :(得分:11)

因为对于高长度而言,设计具有不必要的深度继承是非常糟糕的。唯一合理的继承来自一些 GeneralTuple ,但是我无法想出任何可以被所有n元组共享和使用的代码。 Neiter可以是.NET设计师。

n元组作为(n-1) - 元组加一个元素的递归定义是不自然的,因此不实用,因为在实际元组中所有元素都是相等的。想象一下,你有{1, 2, 3}。根据您的提案有两种方式来表示它:{{1, 2}, 3}{1, {2, 3}},这两种方法都不能合理地被优先考虑,这证明了表示错误,因为它需要人工和方法。除了美丽和非简化的数学定义之外,还有多余的约定。

答案 1 :(得分:6)

TL; DR 由于C#语言不是MATLAB language,不是Wolfram language,因此Prolog language不是F# language。语言设计和类库设计旨在提供生产就绪,功能强大,易于使用,高效,图灵完备的通用语言(参见例如Wikipedia: C# Design Goals)。 C#不是用于在原始哲学或数学意义上表达和操纵思想的语言

为什么带有3个元素的元组不是具有2个元素的元组的子类?

为什么微软的某个人决定按照它的方式编写http://referencesource.microsoft.com/#mscorlib/system/tuple.cs?问问微软的设计师。

这个“为什么”的问题没有真正的生命意义(并且不符合Stack Overflow问题格式)。如果您在我的代码中询问“如何”我可以使用它,例如我如何定义 GeneralTuple ,这将允许我创建一些抽象的通用函数库...那么这样的问题将有一个意义,并将有一个可用的答案。

从我的角度来看,这个设计决定可能是由元组的性质和历史引出的。据我记得,它来自Linda computation model tuples Tuple<T1,T2>Associated memory known as Tuplespace中存在基本数据结构。元组只是简单的数据结构(没有方法和行为的OOP对象),类似于现在所知的Data Transfer Object (DTO)。它总是只是一个简单的数据结构,是关联内存的一部分。要求是简单快速的读/写/传输。这就是今天内置的C#Tuples支持

为什么Tuple<Foo,Bar>不协变(即Tuple<SuperFoo,SuperBar>也是{{1}}?

因为通用类不是这样的。在Stack Overflow上也多次解释了这个问题,参见例如Generic inherited type restriction in C#