This is a bit of a lengthy question, so please bear with me.
I need to create a mapping between a set of strings and corresponding generic method calls for each string. However I’ve run into a compile issue, explained lower down.
In my scenario I am using a Dictionary<>, but the issue exists equally for a List<>. For simplicity I’m using a List<> in the example below.
Consider these three classes:
public abstract class MyBase { /* body omitted */ }
public class MyDerived1 : MyBase { /* body omitted */ }
public class MyDerived2 : MyBase { /* body omitted */ }
And a method in some other class:
public class Test
{
public T GetT<T>() where T : MyBase { /* body omitted */ }
}
In another class, I can declare a List<Func<MyBase>> like this:
public class SomeClass
{
public void SomeFunc()
{
var test = new Test();
var list1 = new List<Func<MyBase>>
{
test.GetT<MyDerived1>,
test.GetT<MyDerived2>
};
}
}
This is all fine and well.
But, what if I want to have a function that return a generic class like this:
public class RetVal<T> where T : MyBase { /* body omitted */ }
public class Test
{
public RetVal<T> GetRetValT<T>() where T : MyBase
{
return null;
}
}
And I want to create an equivalent List<> using this function. i.e. a List>>?
public class Class1
{
public void SomeFunc()
{
var test = new Test();
var list2 = new List<Func<RetVal<MyBase>>>
{
test.GetRetValT<MyDerived1>, // compile error
test.GetRetValT<MyDerived2> // compile error
};
}
}
I get compile errors of Expected a method with 'RetVal<MyBase> GetRetValT()' signature.
So, is there any way around this, or is there an alternative approach that I can use for creating my string…generic method call mappings?
C# only allows covariance on interfaces. That means you cannot cast a
RetVal<MyDerived1>to aRetVal<MyBase>automatically. IfRetValshould be covariant, create an interface for it, like so:Then this code will work: