Question

I have two classes

 public class A
    {
        public A()
        {

        }
    }

    public class B:A
    {
        public B()
        {

        }
    }

and it the code in Main is as follows

    A oa = new B();
    B ob = new A();

Here line 1 compiles successfully while line 2 displays typecasting error. Why this happens. What exactly happens when new B() and new A() gets called?

Was it helpful?

Solution

What exactly happens when new B() and new A() gets called?

  • new A() constructs an object of type A on the heap and returns a reference to it.

  • new B() constructs an object of type B on the heap and returns a reference to it.

Here line 1 compiles successfully while line 2 displays typecasting error. Why this happens.

Since B subclasses A, it is valid for a reference of type A to refer to an object of run-time type B. After all, B is simply a "special case" of A.

However, the converse is not true, because not all As can be considered Bs. Although this is strictly enforced by C#'s safe type-system even if there is no "real" incompatibility, the reasons for such restrictions are natural. Imagine, for example, that B declared a property public int Foo {get; set;}. How would you expect this to behave:

B ob = new A();
ob.Foo = 5;

This is clearly illogical: the real object that the reference is referring to has no such property. Consequently, the compiler prohibits such constructs.

Now imagine you changed your code to:

B b = (B)new A();

Here, you are telling the compiler that the object created, will, at run-time, be assignable to a reference of type B. This will compile fine, but since the assertion is clearly incorrect, a run-time InvalidCastException will be thrown.

To summarize, C#'s type system (if you ignore dynamic and a few special cases) is both static and safe: you will not successfully be able to treat a concrete instance of A as though it were of type B.

OTHER TIPS

You have declared a variable of type B, and then attempted to assign a value of type A to it. You have defined B to be a kind of A, but that doesn't mean that all A's are B's.

Think of it like this:

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

You can do Animal rex = new Dog(), because all dogs are animals, but not Dog fido = new Animal(), because not all animals are dogs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top