I need more information about variance in generics and delegates. The following code snippet does not compile:
Error CS1961 Invalid variance: The ty
TIn = the class knows how to read it, and the implementation is allowed to treat it as a type that is less derived than it actually is. You might pass it an instance that is more derived than expected, but that doesn't matter, because the derived class can do everything that the base class can do.
TOut = the implementation knows to to produce one, and the implementation is allowed to produce a type that is more derived than the caller is expecting. Again, it doesn't matter-- the caller can assign a more derived class to a less derived variable with no problem.
But--
If you pass the class a Func, and you expect the class to be able to call it, then the class will have to be able to produce a TIn and read the TOut. Which is the opposite of the above.
Why can't it? Well, I already mentioned that the class can treat TIn as something that is less derived. If it attempts to call the function with an argument that is less derived, it won't work (what if the function is expecting to be able to call string.Length but the class passes it an object?). Also, if it attempts to read the results of the function as something that is more derived, that will fail as well.
You can eliminate the problem by eliminating the variance-- get rid of the in and out keywords-- which will render the class unable to substitute less/more derived types (this is called "invariance") but will allow you to both read and write the types.