I have the following code:
static Func<object, string> s_objToString = (x) => x.ToString();
static Func<string, string> s_stringToString = s_objToString; //compiles
static Func<int, string> s_intToString = s_objToString; //error
The second line compiles but the third line fails to compile with error:
Cannot implicitly convert type '
System.Func<object,string>
' to 'System.Func<int,string>
'
Why is that?
I understand that with genetics although string is derived from object a List<string>
does not derive from List<object>
, but here object
to string
works and object
to int
fails, why?
OK let's say I understood why; the question now is there a way around it (other then defining MyInt
class to box int
because Func<object,string>
to Func<MyInt,string>
works)?
It is because Func
is defined as Func<in T, out TResult>
, MSDN is here, so T
is contra-variant with in
keyword, that is, you can use either the type you specified or any type that is less derived, but remember that co-variance and contra-variance do not support for value type:
Why covariance and contravariance do not support value type
So, it works for string
but does not work out with int
. You might need to read more about covariance and contravariance:
Because co/contra-variance doesn't work for value types.
Please take a look here
Variance is supported only if a type parameter is a reference type. Variance is not supported for value types.
The following doesn’t compile either:
// int is a value type, so the code doesn't compile.
IEnumerable<Object> objects = new List<int>(); // Compiler error here.
来源:https://stackoverflow.com/questions/13025176/conversion-from-funcobject-string-to-funcstring-string-works-but-to-funcint