开发者

Type casting error and constructor

开发者 https://www.devze.com 2023-01-14 19:33 出处:网络
I have two classes public class A { public A() { } } public class B:A { public B() { }开发者_JAVA百科 } and it the code in Main is as follows

I have two classes

 public class A
    {
        public A()
        {

        }
    }

    public class B:A
    {
        public B()
        {

        }开发者_JAVA百科
    }

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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消