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:
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
?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With