The following code doesn't compile (error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>'
):
class A<T> {
void Method(T obj) {
Converter<T, string> toString = Convert.ToString;
// this doesn't work either (on .NET 4):
Converter<object, string> toString2 = Convert.ToString;
Converter<T, string> toString3 = toString2;
}
}
however, this does:
class A<T> {
void Method(T obj) {
// o is a T, and Convert.ToString(o) is using
// string Convert.ToString(object o)
Converter<T, string> toString = o => Convert.ToString(o);
}
}
In c# 4, co/contra-variant delegates can be assigned to each other, and delegates can be created from co/contra-variant methods, so the ToString(object)
method can be used as a Converter<T, string>
, as T
is always guarenteed to be convertable to an object
.
So, the first example (method group overload resolution) should be finding the only applicable method string Convert.ToString(object o)
, the same as the method call overload resolution. Why is the method group & method call overload resolution producing different results?
This has to do with the fact that variance is not applicable to value types, so if you restrict T
like where T : class
you get variance on T
and the first snippet of code will compile.
From the Covariance and Contravariance FAQ:
Variance is supported only if a type parameter is a reference type. Variance is not supported for value types.
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