Why explicit conversion required to assign base class to derived class? But not required to do the reverse

11,077

Solution 1

When you use explicit conversion, in your case, you are telling the compiler that you know what is going on. If you were to compile your code, removing d = a;, and you tried to access a public member on d, and exception would be thrown. That is because, in this instance, the animal is not a dog. You explicitly created an animal and assigned it to a.

Explicit conversion allows you to do thing when you know the conversion will work.

public class MyClass
{
    public animal MyAnimal { get; private set; }

    public MyClass ()
    {
        MyAnimal = new dog ();
    }

    public void SetAge (int Age)
    {
        ((dog)MyAnimal).age = Age;
    }
}

In this case, we know that MyAnimal is actually a dog, so we can do an explicit cast to it. All of this works because of inheritance. Because inheritance does not work both ways, the complier will not allow an implicit up cast--you must do it explicitly.

We know that when a class inherits from its base class, it takes with it the public properties and methods. You cannot say that your reference to an animal will always contain the properties and methods of a dog.

Solution 2

All dogs are animals, but not all animals are dogs. Implicit conversion is not allowed because your a might not actually be a d.

Solution 3

Its a simple rule of inheritance cast. For example: Dog is Animal but reverse is not true - Animal is Dog. There may be number of sub-classes of Animal.

class Animal {}
class Dog : Animal {}
class Cat : Animal {}

Animal a=new Cat(); // OK
a=new Dog(); // OK

Cat c=a; //Invalid - var a might contains reference of Cat or Dog
Cat d=(Cat)a; // Throws InvalidCastException exception because "a" has ref. of Dog

So, super class reference variable can hold reference of sub-class object without cast but when you assign reference from the super class reference variable to the sub-class reference variable you must have to cast.

Have a look at MSDN article - How to: Safely Cast by Using as and is Operators (C# Programming Guide).

Solution 4

Think of it this way, all dogs are already animals but not all animals are dogs. To assign an animal to a dog you must first convert it to a dog.

Solution 5

What happen internally that derived class can assigned to base but doing the reverse explicit conversion is required? Same result found even both base and derived class contains same member.

Almost nothing is happening internally, in either case. The object is not being modified, or copied; rather, it's simply that a reference to it is being stored in a new variable with a different type.

The implicit conversion from dog to animal is allowed because if a dog variable can hold a reference to an object, then the object must be a dog or a poodle or whatnot, so an animal variable can also hold a reference to it.

By contrast, an explicit conversion is required from animal to dog because the animal object really might not be a dog, in which case the run-time system will raise an exception. (Remember when I said that "almost nothing is happening internally"? It's "almost nothing" because the run-time system will have to check to ensure that the object is a dog, and to raise an exception otherwise.)

This is a language design decision — we could definitely create a language that's exactly like C#, except that dog d = a; is equivalent to dog d = (dog) a;, but the designers of C# (and many similar languages) felt that it would be confusing for dog d = a; to raise a run-time exception sometimes. The explicit cast makes clear that an exception is possible unless a refers to a dog.

Share:
11,077
paul sim
Author by

paul sim

Updated on July 23, 2022

Comments

  • paul sim
    paul sim almost 2 years

    I have a base class and a derived class as bellow

    public class animal
    {
        public string name { get; set; }
    }
    
    public class dog : animal
    {
        public int age { get; set; }
        public string type { get; set; }
    }
    

    uses:

    animal a = new animal();
    
    dog d = new dog();
    
    a = d; //compiled
    
    d = a; //Error:Cannot implicitly convert type 'animal' to 'dog'.
    
    d = (dog)a; // compiled
    

    What happen internally that derived class can assigned to base but doing the reverse explicit conversion is required? Same result found even both base and derived class contains same member.

  • Matthias
    Matthias over 12 years
    Lets convert all animals to dogs :D
  • paul sim
    paul sim over 12 years
    thanks Marty..actually i am looking for some internal explanation...what happen in memory allocation..why CLR cannt allow implicit conversion...and all the internal working in respect to CLR,memory management...
  • zacknight95
    zacknight95 about 2 years
    A Simpler yet clear explanation