Upper-Bound/Lower-Bound Inferences and fixing
c#
Solution
I'll try my best to describe it more clearly. Worst case, I describe it differently.
The upper/lower inference is one part of a phased approach to type inference with regard to type arguments that are used for a particular generic method call. Obviously, upper/lower inference won't be applied if in the first phase if the argument (E) is explicitly typed. e.g.:
given
public static T Choose<T>(T first, T second) {
return (rand.Next(2) == 0)? first: second;
}
I can invoke `Choose` with explicit type arguments:
Choose<String>("first", "second");
With regard to the upper- or lower-bounds inference, there are some implications throughout 7.5.2 that decide whether lower- or upper-bounds inference is even applicable. For example, 7.5.2.9 (and .10) detail that the type parameter is unfixed for either upper- or lower-bounds inference to occur. 7.5.2.5 details that a type parameter is only unfixed when that type parameter depends on another unfixed type parameter. For example
IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> e,
Func<TSource, Result> f)
`TResult` "depends on" `TSource`, because the type of `TSource` could possibly determine the type of `TResult`. e.g. with a call like `Select(c, e->Name)`, `TResult` depends on the type of `Name` in `TSource`.
In terms of upper- and lower-bounds inferences, for a given unfixed type parameter (X) whose type (V) is not explicitly declared (see first paragraph), upper or lower bounds of type argument (E) of type U are deduced. If the type parameter is covariant (has `out` modifier) and one of the types in the lower-bound set is a candidate for the parameter, then a lower-bound inference occurred. Conversely, if the type parameter is contravariant (has 'in' modifier) and one of the types in the upper-bound set is a candidate for the parameter, then an upper-bound inference occurred. e.g. with `Select(c, e->e.Name)` and `c` was `IEnumerable<Mammal>` then the compiler would infer an lower bound of `Mammal` because the type parameter in `IEnumerable` is covariant (e.g. it's declared `IEnumerable<out T>`. If it were declared `IEnumerable<in T>` then an upper-bound would be inferred. And if it were declared `Enumerabale<T>`--with no `in` or `out` then it would be invariant and neither upper- nor lower-bounds inference would apply.)
Clearly, if parameter type can be neither covariant nor contravariant then an exact match must occur
Problem
In the C# 4.0 Spec 7.5.2.9: A lower-bound inference from a type U to a type V is made as follows: - If V is one of the unfixed Xi, then U is added to the set of lower bounds for Xi. - [...] I've gone over this section many times. Lacking a section reference, this definition reads like a circular reference. So, I expect to find a grammer production or section reference nearby to clarify..which I do not. This section also ties in Fixing which suffers from similar definition issues. What is an `upper-bound inference` vs a `lower-bound inference`?