ares_games
ares_games

Reputation: 1067

Recasting to base class in C#

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

Answers (3)

Jon Hanna
Jon Hanna

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

Yury Schkatula
Yury Schkatula

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

BradleyDotNET
BradleyDotNET

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

Related Questions