Reputation: 10322
I created some methods that use nested type parameters generic types in the parameter declaration:
public void Foo(IList<Pair<double, IList<double>>> myParameter)
{ // code goes here
}
What I wanted to achieve was to force this method to accept 4 types of variables:
List<Pair<double, List<double>>> myVar
List<Pair<double, double[]>> myVar
Pair<double, List<double>>[] myVar
Pair<double, double[]>[] myVar
But it seems that second, nested interface cannot be converted on-the-fly by C#. While trying to pass some of variables listed above to my method, I get error:
Argument 1: Cannot convert from System.Collections.Generic.List<...> to Cannot convert from System.Collections.Generic.IList<...>
Do I really need to create two aliases for this method to handle this problem? Or maybe there is some kind of trick that I could use to overcome this problem?
Upvotes: 2
Views: 4862
Reputation: 2265
You can use generic constraints in C# 2.0+
void Foo<TList>(IList<Pair<double, TList>> myParameter)
where TList : IList<double>
C# has trouble with the type inference on this one though, so you will need to specify during calling.
Upvotes: 2
Reputation: 49218
Your code leads to a variance problem.
The inner IList<double>
would allow you to assign List<double>
even if you originally passed a double[]
, which would break type safety.
(This occurs fore the same reason as List<Orange>
may not be treated as a List<Fruit>
: You could push apples into it.)
In order to achieve correct variance behaviour, you'll have to ensure immutability as through the use of IEnumerable<T>
s instead of IList<T>
s (just works under .NET 4.0).
The previous versions of C# aren't able to handle variance at all!
Upvotes: 5
Reputation: 74560
Without knowing what you are passing, the issue here is more than likely due to the fact that you don't have variance on generic type parameters.
Fortunately, in C# 4.0, this exists, and I'd be willing to guess that you could use IEnumerable<double>
as the inner type parameter and it would work (unless you have a need to mutate the list as opposed to just iterating it.
If you are not able to use C# 4.0, then you are going to have to change the type parameter of your List<T>
variable to the specific type requested.
Upvotes: 1