Connecting Tech Pros Worldwide Help | Site Map
 
 
LinkBack Thread Tools Search this Thread
  #1  
Old November 17th, 2005, 09:15 AM
matty.hall@gmail.com
Guest
 
Posts: n/a
Default Casting List<> of derived class to List<> of base class?

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 { }
}

  #2  
Old November 17th, 2005, 09:15 AM
matty.hall@gmail.com
Guest
 
Posts: n/a
Default 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?

  #3  
Old November 17th, 2005, 09:15 AM
Jon Skeet [C# MVP]
Guest
 
Posts: n/a
Default 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
  #4  
Old November 17th, 2005, 09:15 AM
matty.hall@gmail.com
Guest
 
Posts: n/a
Default 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 { }
}

  #5  
Old November 17th, 2005, 09:15 AM
Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
Default 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]


 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 205,248 network members.