在 C# 4.0 规范 7.5.2.9 中:
从 U 型到 V 型的下限推断如下:
- 如果 V 是未固定的 X i之一,则将 U 添加到 X i的下限集合中。
- [...]
这部分我已经看过很多次了。由于缺少章节引用,这个定义读起来就像一个循环引用。所以,我希望在附近找到语法制作或章节参考来澄清......我没有。本节还与存在类似定义问题 的Fixing相关联。
什么是 a upper-bound inference
vs a lower-bound inference
?
在 C# 4.0 规范 7.5.2.9 中:
从 U 型到 V 型的下限推断如下:
这部分我已经看过很多次了。由于缺少章节引用,这个定义读起来就像一个循环引用。所以,我希望在附近找到语法制作或章节参考来澄清......我没有。本节还与存在类似定义问题 的Fixing相关联。
什么是 a upper-bound inference
vs a lower-bound inference
?
我会尽力把它描述得更清楚。最坏的情况,我用不同的方式描述它。
上/下推断是关于用于特定泛型方法调用的类型参数的类型推断的分阶段方法的一部分。显然,如果在第一阶段显式键入参数 (E),则不会应用上/下推理。例如:
给定
public static T Choose<T>(T first, T second) {
return (rand.Next(2) == 0)? first: second;
}
我可以Choose
使用显式类型参数调用:
Choose<String>("first", "second");
关于上限或下限推断,在整个 7.5.2 中都有一些含义,它们决定了下限或上限推断是否适用。例如,7.5.2.9(和 .10)详细说明类型参数对于发生上限或下限推断是不固定的。7.5.2.5 详细说明了一个类型参数仅在该类型参数依赖于另一个不固定类型参数时才是不固定的。例如
IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> e,
Func<TSource, Result> f)
TResult
“取决于” TSource
,因为 的类型TSource
可能决定 的类型TResult
。例如,与调用类似Select(c, e->Name)
,TResult
取决于Name
in的类型TSource
。
就上限和下限推断而言,对于未显式声明类型 (V) 的给定非固定类型参数 (X)(参见第一段),推导出类型 U 的类型实参 (E) 的上限或下限. 如果类型参数是协变的(具有out
修饰符)并且下限集中的类型之一是参数的候选者,则发生下限推断。相反,如果类型参数是逆变的(具有 'in' 修饰符)并且上限集中的类型之一是参数的候选者,则发生上限推断。例如 with Select(c, e->e.Name)
and c
wasIEnumerable<Mammal>
然后编译器会推断出的下限因为Mammal
类型参数 inIEnumerable
是协变的(例如它被声明IEnumerable<out T>
. 如果它被声明,IEnumerable<in T>
那么将推断出一个上限。如果它被声明Enumerabale<T>
——没有in
或out
那么它将是不变的,并且上限和下限推断都不会适用。)
显然,如果参数类型既不能是协变的也不能是逆变的,那么必须发生完全匹配