推断的模板类型和隐式类型转换有什么问题?

时间:2015-03-21 08:20:32

标签: c# templates generics d

我正在阅读Andrei Alexandrescu的“D编程语言”,一句话让我感到困惑。考虑这样的代码(第138页):

T[] find(T)(T[] haystack, T needle) {
   while (haystack.length > 0 && haystack[0] != needle) {
      haystack = haystack[1 .. $];
   }
   return haystack;
}

并致电(第140页):

double[] a = [ 1.0, 2.5, 2.0, 3.4 ];
a = find(a, 2); // Error! ' find(double[], int)' undefined

解释(代码下面的段落):

  

如果我们足够眯眼,我们确实看到调用者在这种情况下的意图是拥有T = double,并从intdouble的良好隐式转换中受益。然而,在一般情况下,让语言同时组合地尝试隐式转换和类型推导是一个冒险的命题,因此D不会尝试做所有这些。

我感到困惑,因为像C#这样的语言试图推断出类型 - 如果它不能做到这一点,用户会得到错误,但是如果可以的话,它就可以了。 C#和它一起生活了几年,我没有听到任何关于这个功能如何破坏某个人日子的故事。

所以我的问题就是这个 - 在上面的例子中推断类型涉及哪些危险?

我只能看到优点,很容易编写泛型函数,并且很容易调用它。否则,您必须在泛型类/函数中引入更多参数,并编写表示允许转换的特殊约束,仅用于推断类型。

1 个答案:

答案 0 :(得分:1)

首先要注意的是,它没有说类型演绎存在问题,而且类型演绎隐式转换同时存在问题

所以,如果你有:

a = find(a, 2.0);

然后很高兴推断double为类型。

如果明确输入为double,则很高兴推断2应隐式转换为2.0

它不会同时发生的事情。

现在,C#确实这样做了。而且我认为在很大程度上我同意你的看法,它通常很方便,而且通常运作良好。

同时它确实令人困惑,特别是在导致不止一次同样合理的过载的情况下。

Why type inference and implicit operator is not working in the following situations?Why does Assert.AreEqual on custom struct with implicit conversion operator fail?都是关于为什么隐式转化和类型推断的特定组合不起作用的问题。

Unexpected effect of implicit cast on delegate type inference还有其他因素,但是再次拒绝考虑可能匹配列表中的方法,因为参数类型不匹配意味着问题没有发生。

如果答案总是“因为你在同一时间进行隐式转换和类型推断,并且不支持”,那么它们会更简单。这就是D的答案。

另一方面,这种问题不会经常出现,所以我仍然赞成C#设计决定允许两者,但是有一些问题意味着它仍然是一个合理的设计决定,不允许它们。 / p>