Connecting Tech Pros Worldwide Help | Site Map

Casting List<> of derived class to List<> of base class?

matty.hall@gmail.com
Guest
 
Posts: n/a
#1: Nov 17 '05
I have two classes: a base class (BaseClass) and a class deriving from
it (DerivedClass). I have a List<DerivedClass> that for various
reasons needs to be of that type, and not a List<BaseClass>. However, I
need to cast that list to a List<BaseClass> and it is not working. The
code is below. I get the following exception:

"Unable to cast object of type 'System.Collections.Generic.List`1' to
type 'System.Collections.Generic.List`1'."

Replacing the line "baseClasses = (List<BaseClass>) temp;" with
"baseClasses = (List<BaseClass>) derivedClasses" causes the compiler to
show an error:

"Cannot convert type
'System.Collections.Generic.List<ConsoleApplicatio n1.DerivedClass>' to
'System.Collections.Generic.List<ConsoleApplicatio n1.BaseClass>'"

Is there anyway to accomplish this? Code follows...


using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<DerivedClass> derivedClasses;
List<BaseClass> baseClasses;
object temp;

derivedClasses = new List<DerivedClass>();
temp = derivedClasses;
baseClasses = (List<BaseClass>) temp;
}
}

public abstract class BaseClass {}
public abstract class DerivedClass : BaseClass { }
}

matty.hall@gmail.com
Guest
 
Posts: n/a
#2: Nov 17 '05

re: Casting List<> of derived class to List<> of base class?


One more thing...

I do know about List<>.ConvertAll. However, I can't use this because
the type of the Derived class is not known at compile time (i.e. there
will be DerivedClassOne, DerivedClassTwo, etc and we don't know which
one it is because this conversion is actually happening in the base
class, which isn't a fact show in the code above, which I omitted to
keep the pasted code short).

The problem is that doing doing ConvertAll() with a Converter declared
as Converter<BaseClass, BaseClass> throws a compile time error "The
type arguments for method
'System.Collections.Generic.List<ConsoleApplicatio n1.DerivedClass>.ConvertAll<TOutput>(System.Conver ter<ConsoleApplication1.DerivedClass,TOutput>)'
cannot be inferred from the usage. Try specifying the type arguments
explicitly."

Alternatively, at runtime I know the type of the derived class from
GetType(). However, I don't know how (or if it is even possible) to
declare a generic type using runtime type information (i.e. something
like Converter<this.GetType(), BaseClass>).

Any thoughts?

Jon Skeet [C# MVP]
Guest
 
Posts: n/a
#3: Nov 17 '05

re: Casting List<> of derived class to List<> of base class?


<matty.hall@gmail.com> wrote:[color=blue]
> I have two classes: a base class (BaseClass) and a class deriving from
> it (DerivedClass). I have a List<DerivedClass> that for various
> reasons needs to be of that type, and not a List<BaseClass>. However, I
> need to cast that list to a List<BaseClass> and it is not working. The
> code is below. I get the following exception:
>
> "Unable to cast object of type 'System.Collections.Generic.List`1' to
> type 'System.Collections.Generic.List`1'."
>
> Replacing the line "baseClasses = (List<BaseClass>) temp;" with
> "baseClasses = (List<BaseClass>) derivedClasses" causes the compiler to
> show an error:
>
> "Cannot convert type
> 'System.Collections.Generic.List<ConsoleApplicatio n1.DerivedClass>' to
> 'System.Collections.Generic.List<ConsoleApplicatio n1.BaseClass>'"
>
> Is there anyway to accomplish this? Code follows...[/color]

No. List<DerivedClass> isn't derived from List<BaseClass>. If it were,
you'd be able to do:

List<String> x = new List<String>();
List<Object> y = x;

y.Add (new Object()); // Bang! x is only meant to contain strings...

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
matty.hall@gmail.com
Guest
 
Posts: n/a
#4: Nov 17 '05

re: Casting List<> of derived class to List<> of base class?


FWIW, this is what actually works:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<DerivedClass> derivedClasses;
BaseClass[] baseClasses;

derivedClasses = new List<DerivedClass>();
baseClasses = derivedClasses.ToArray();
}
}

public abstract class BaseClass { }
public class DerivedClass : BaseClass { }
}

Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#5: Nov 17 '05

re: Casting List<> of derived class to List<> of base class?


Yes, that works, but the problem that Jon points out still exists. If
you tried to take baseClasses and populate a List<DerivedClass> with it, it
could fail at runtime. This is the risk you run if you have to go the other
way.

--
- Nicholas Paldino [.NET/C# MVP]
- casperOne@caspershouse.com

<matty.hall@gmail.com> wrote in message
news:1126496292.673417.208690@f14g2000cwb.googlegr oups.com...[color=blue]
> FWIW, this is what actually works:
>
> using System;
> using System.Collections.Generic;
>
> namespace ConsoleApplication1
> {
> class Program
> {
> static void Main(string[] args)
> {
> List<DerivedClass> derivedClasses;
> BaseClass[] baseClasses;
>
> derivedClasses = new List<DerivedClass>();
> baseClasses = derivedClasses.ToArray();
> }
> }
>
> public abstract class BaseClass { }
> public class DerivedClass : BaseClass { }
> }
>[/color]


Closed Thread