0

(How) can I cast a derived class type in place of a base class? (I think it's cast I'm looking for - I think this is a simple thing to do but every answer I click on is wrapped in complexity)

E.g. if I have declared somewhere I want a list of BASECLASS - can I not put in to this list any of its DERIVEDCLASSES ? It makes sense that I could, because they'll have all the same properties (but with some extras)

class baseClass_to_derivedClass
{
    public class Animal { }

    public class Giraffe : Animal { }

    public void CallMeMethod()
    {
        List<Animal> x;
        x = new List<Giraffe>(); // This line doesn't compile
    }
}
jamheadart
  • 5,047
  • 4
  • 32
  • 63
  • No, that does *not* make sense. Imagine you´d have a list of `Giraffe`. If you **were** able to do this, you could simply add a lion into that list, because both are `Animals`. – MakePeaceGreatAgain Aug 20 '18 at 12:16
  • I won't be adding different `animals` to the list, the list is just defined as `animals` and then I want to re-define it as a list of more specific `giraffes` – jamheadart Aug 20 '18 at 12:18
  • In generic types this isn't avaliable, it's called **covariance**. You can find more details in [this article](https://weblogs.asp.net/dixin/understanding-csharp-covariance-and-contravariance-1-delegates). – Chayim Friedman Aug 20 '18 at 12:20
  • I can't add any BASE animal to my list of GIRAFFES. I want to limit things that can fit in my list `X` by saying it must be an `animal` or a derived type - later on this will be re-defined as any type of animal... but after being defined as `giraffe` it will only allow `giraffe`. It's not a list of `animal` any more. It makes total sense, there's just other problems that can occur if it allows people to then transfer a list of BASE animals to a derived GIRAFFE list. That doesn't make sense... – jamheadart Aug 20 '18 at 12:29
  • 1
    No, it *doesn't* make total sense for a *variable* to have it's type defined at one point and then to *redefine* the variable later to have a different type. `x` is a `List`. That's what it is. That's what it'll always be. Whatever is assigned to `x`, whatever else is true about it, must be a `List` that can contain `Animal`s and have them added and removed. – Damien_The_Unbeliever Aug 20 '18 at 12:31
  • If it's a derived type of the initial definition, then why not? If I want to say in a base class that its property X must be an animal, then later on in a derived class be more specific about the type and say it has to be a giraffe, then what's wrong with that? I've just read in a link which looks like I'm supposed to be using an interface to define the animal and then a list to specify which type. So what I'm asking does make total sense, it's just there's issues with the way I wanted to apply it in c#. – jamheadart Aug 20 '18 at 12:39
  • In general only because a `Giraffe` is an `Animal` doesn´t mean that a `List` is a `List`. If you want to restrict your list to a `Giraffe`, then *define* your list as of that type. But you could of course cast every object stored within that list to its base-class and create a new list for those: `animals = giraffes.Cast().ToList()`. – MakePeaceGreatAgain Aug 20 '18 at 12:42
  • All I did was swap `List x` with `IEnumerable x` and lo and behold the code works perfectly. – jamheadart Aug 20 '18 at 12:43
  • 1
    Sure, because you can´t *add* a lion to an `IEnumerable`, but to a `List`. That´s why converting to the former is okay and doesn´t cause any problems. – MakePeaceGreatAgain Aug 20 '18 at 12:45
  • Yes, but what I was asking was complete and utter convoluted idiot gibberish. – jamheadart Aug 20 '18 at 12:48

0 Answers0