2010-09-06 3 views
0

У меня есть два классаТипа и конструктор

public class A 
    { 
     public A() 
     { 

     } 
    } 

    public class B:A 
    { 
     public B() 
     { 

     } 
    } 

и код в Main выглядит следующим образом

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

Здесь линия 1 успешно компилируется в то время как 2-й строки типажей ошибки. Почему это происходит. Что именно происходит, когда вызывается new B() и new A()?

ответ

2

Что именно происходит, когда вызывается новый B() и новый A()?

  • new A() строит объект типа A в куче и возвращает ссылку на него.

  • new B() создает объект типа B в куче и возвращает ссылку на него.

Здесь линия 1 компилируется успешно в то время как 2-й строке типажей ошибку. Почему это происходит.

С B подклассы A, оно справедливо для ссылки типа A ссылаться на объект времени выполнения типа B. В конце концов, B - это просто «частный случай» A.

Однако обратное неверно, поскольку не все A s можно рассматривать как B s. Хотя это строго соблюдается C# безопасным типом системы, даже если нет «реальной» несовместимости, причины таких ограничений естественны. Представьте себе, например, что B объявили о собственности public int Foo {get; set;}. Как бы вы ожидать, что это себя:

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

Это явно нелогично: в реальный объект, ссылка на который указывает ссылка не имеет такого свойства. Следовательно, компилятор запрещает такие конструкции.

Теперь представьте, что вы изменили код:

B b = (B)new A();

Здесь вы сообщаете компилятору, что созданный объект, будет, в время выполнения, могли быть переданы ссылки типа B , Это будет компилироваться отлично, но поскольку утверждение явно неверно, будет запущено время выполнения InvalidCastException.

Резюмируя, система типа С # (если игнорировать dynamic и несколько специальных случаев) является одновременно статическим и безопасно: вы не будете успешно быть в состоянии обработать конкретный экземпляр A, как если бы это было типа B.

7

Вы указали переменную типа B, а затем попытались присвоить ей значение типа A. Вы определили B как вид A, но это не значит, что все A - это B.

Думай об этом, как это:

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

Вы можете сделать Animal rex = new Dog(), потому что все собаки являются животные, но не Dog fido = new Animal(), потому что не все животные собаки.