Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variance in Func<> arguments

I've been trying to do something like

Func<string, bool> f
Func<object, bool> F = f;

and the compiler raises the following error:

Cannot implicitly convert type 'System.Func<string,bool>' to 'System.Func<object,bool>'

However, we obviously can do object x = "123"

like image 637
Oscar Mederos Avatar asked Aug 17 '26 08:08

Oscar Mederos


2 Answers

Imagine if you had done this:

Func<string, bool> fStr = str => str.Length > 10;
Func<object, bool> fObj = fStr;

Well, according to the signature of fObj, you should be able to call it with any argument like this:

fObj(7);

Which is obviously invalid for fStr.

like image 134
p.s.w.g Avatar answered Aug 18 '26 22:08

p.s.w.g


The delegate type Func<in T, out TResult> is clearly contravariant in its first type argument T. A "func" that can take in any object can also take in a string, so a Func<object, X> "is a" Func<string, X>, so this is contravariance in the in type T.

You are trying to go the other way. That will only work if you happen to know that the run-time type is really a Func<object, bool>, and you will need explicit cast syntax to inform the compiler of your knowledge. If the run-time type is not correct, the explicit cast will fail.

Valid example:

Func<object, bool> f1 = XXX;
Func<string, bool> f2 = f1;                      // OK, implicit
Func<object, bool> f3 = (Func<object, bool>)f2;  // OK, explicit
like image 32
Jeppe Stig Nielsen Avatar answered Aug 18 '26 23:08

Jeppe Stig Nielsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!