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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • matty.hall@gmail.com

    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<DerivedCla ss> 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.Collect ions.Generic.Li st`1' to
    type 'System.Collect ions.Generic.Li st`1'."

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

    "Cannot convert type
    'System.Collect ions.Generic.Li st<ConsoleAppli cation1.Derived Class>' to
    'System.Collect ions.Generic.Li st<ConsoleAppli cation1.BaseCla ss>'"

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


    using System;
    using System.Collecti ons.Generic;

    namespace ConsoleApplicat ion1
    {
    class Program
    {
    static void Main(string[] args)
    {
    List<DerivedCla ss> derivedClasses;
    List<BaseClass> baseClasses;
    object temp;

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

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

  • matty.hall@gmail.com

    #2
    Re: Casting List&lt;&gt; of derived class to List&lt;&gt; of base class?

    One more thing...

    I do know about List<>.ConvertA ll. 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<BaseC lass, BaseClass> throws a compile time error "The
    type arguments for method
    'System.Collect ions.Generic.Li st<ConsoleAppli cation1.Derived Class>.ConvertA ll<TOutput>(Sys tem.Converter<C onsoleApplicati on1.DerivedClas s,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?

    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: Casting List&lt;&gt; of derived class to List&lt;&gt; of base class?

      <matty.hall@gma il.com> wrote:[color=blue]
      > I have two classes: a base class (BaseClass) and a class deriving from
      > it (DerivedClass). I have a List<DerivedCla ss> 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.Collect ions.Generic.Li st`1' to
      > type 'System.Collect ions.Generic.Li st`1'."
      >
      > Replacing the line "baseClasse s = (List<BaseClass >) temp;" with
      > "baseClasse s = (List<BaseClass >) derivedClasses" causes the compiler to
      > show an error:
      >
      > "Cannot convert type
      > 'System.Collect ions.Generic.Li st<ConsoleAppli cation1.Derived Class>' to
      > 'System.Collect ions.Generic.Li st<ConsoleAppli cation1.BaseCla ss>'"
      >
      > Is there anyway to accomplish this? Code follows...[/color]

      No. List<DerivedCla ss> 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.co m>
      Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

      If replying to the group, please do not mail me too

      Comment

      • matty.hall@gmail.com

        #4
        Re: Casting List&lt;&gt; of derived class to List&lt;&gt; of base class?

        FWIW, this is what actually works:

        using System;
        using System.Collecti ons.Generic;

        namespace ConsoleApplicat ion1
        {
        class Program
        {
        static void Main(string[] args)
        {
        List<DerivedCla ss> derivedClasses;
        BaseClass[] baseClasses;

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

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

        Comment

        • Nicholas Paldino [.NET/C# MVP]

          #5
          Re: Casting List&lt;&gt; of derived class to List&lt;&gt; 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<DerivedCla ss> 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@caspe rshouse.com

          <matty.hall@gma il.com> wrote in message
          news:1126496292 .673417.208690@ f14g2000cwb.goo glegroups.com.. .[color=blue]
          > FWIW, this is what actually works:
          >
          > using System;
          > using System.Collecti ons.Generic;
          >
          > namespace ConsoleApplicat ion1
          > {
          > class Program
          > {
          > static void Main(string[] args)
          > {
          > List<DerivedCla ss> derivedClasses;
          > BaseClass[] baseClasses;
          >
          > derivedClasses = new List<DerivedCla ss>();
          > baseClasses = derivedClasses. ToArray();
          > }
          > }
          >
          > public abstract class BaseClass { }
          > public class DerivedClass : BaseClass { }
          > }
          >[/color]


          Comment

          Working...