Reputation: 1067
In the following C# setup a class A derived from class X and some method getting a list of List as parameter,
class X
{...};
class A : X
{...};
List<A> listA;
List<X> listX;
void SomeMethod(ref List<X>)
{...};
is there any way to use that same method for class A (which was derived from X)? Recasting that list from A to X seems to not work.
SomeMethod(ref listX); // Works
SomeMethod(ref (List<X>)listA); // Does not work
Upvotes: 2
Views: 159
Reputation: 113322
Two possibilities.
One, redefine void SomeMethod(List<X> list)
as void SomeMethod(IEnumerable<X> list)
.
Because the IEnumerable<T>
is covariant, you can pass an IEnumerable<A>
as to a method with an IEnumerable<X>
parameter, and it will work.
Two, redefine void SomeMethod(List<X> list)
as void SomeMethod<T>(List<T> list) where T : X
.
Here you have a generic SomeMethod
that will work with lists of any type derived from X
, including X
itself.
(Even better if you can is to define the method as void SomeMethod<T>(List<T> list)
[without the where
] or better still, as SomeMethod<T>(IEnumerable<T> list)
as then you've a method applicable to even more cases than those you are currently thinking about, but I'm going to assume you need to make use of some features of X
and those therefore aren't viable).
Note also that as people have said the ref
is unusual here (I just took it out in the above), and it also causes further problems. To use ref
you need an assignable variable (a local variable, a parameter, a settable property or an array access) of the appropriate type, as ref
needs to be able to assign as well as access. Hence you can never cast when passing to a ref
variable as SomeMethod(ref (List<X>)listA)
attempts to do, even if listA
could be cast to List<X>
(which it can't anyway.
Upvotes: 3
Reputation: 5369
Sorry for answering not to your direct question. I'd recommend you to get rid of List<A> and use List<X> both places. Create instances of A and add them to List<X>.
Now according to your direct question. It's possible as @BradleyDotNet answered. See this URL for more details and examples: https://msdn.microsoft.com/ru-ru/library/dd799517(v=vs.110).aspx
Upvotes: 1
Reputation: 61369
Actually, it will already work because IEnumerable
is covariant on its generic type parameter.
If you modify your signature like this:
void SomeMethod(ref IEnumerable<X>)
{...};
Then you can pass a List<X>
or a List<A>
to it and be just fine.
As a total aside, its very weird that you are passing that by ref
. You usually don't pass reference types that way.
Upvotes: 4