2010-08-15 2 views
1

У меня есть класс продукта в C#, который наследуется от другого класса продуктаПроблемы с явной отливкой

using ExternalAssemb.ProductA; 

public class MyProduct : ProductA 
{ 
    //.... 
} 

Я пытаюсь сделать явное приведение из ProductA, который находится в DLL я ссылаться, но это говорит мне, что это не в состоянии бросить

MyProduct myProduct = (MyProduct)productAobject; 

Результат :: System.InvalidCastException: Не удается привести объект типа 'ExternalAssemb.ProductA' к типу 'MyAssembly.MyProduct'.

Что я делаю неправильно?

ответ

5

Вы можете бросить ProductA ссылку на MyProduct ссылки, но только, если он на самом деле указывает на MyProductA или его ребенка.

То, что вы делаете, пытается рассматривать родителя как ребенка, это не работает. Скорее, вы можете относиться к ребенку как к родительскому, потому что он равен, как родитель.

Подумайте об общем примере, когда базовый класс называется Shape и имеет такие дети, как Square и Circle. Учитывая ссылку Shape, вы можете назначить ему любой ребенок. Но если ссылка относится к Circle, вы не можете отдать ее на Square. Это имеет смысл, потому что все круги являются фигурами, но ни один из кругов не представляет собой квадратов.

Надеемся, что примеры помогут.

+0

или явного оператора литья осуществляется для ' ProductA' – zerkms

+1

@zerkms: Это правда, но это тоже отдельная вещь из естественного наследства. Ничто не мешает мне, чтобы «Aardvark» определял явное приведение к «Building», но это не имеет ничего общего с aardvarks, фактически являющимся зданиями. Вместо этого экземпляр «Aarvark» должен вернуть экземпляр «Building», возможно, создав его.Короче говоря, это похоже на кастинг, но это не «действительно» кастинг. –

+0

, если я брошу MyProduct на ProductA, как мне добраться до свойств MyProduct. Должен ли я делать это каждый раз? ((MyProduct) ProductA) .MyProductProperty. – user204588

1

Каждый MyProduct также является ProductA, но обратное неверно. productAobject - это явный пример ProductA; это вовсе не MyProduct.

Аналогично, если другой класс:

public class FooProduct : ProductA 
{ 
    //.... 
} 

... Вы не могли бы сделать это:

ProductA myFooProduct = new FooProduct(); 
MyProduct myProduct = (MyProduct)myFooProduct; 

... так FooProduct не наследует от MyProduct.

Правило: вы можете использовать только экземпляр класса для себя или одного из его классов-предков. Вы не можете отдать его какому-либо потомку или другому классу sibling/cousin в дереве наследования.

Помните, что мы говорим о фактическом типе экземпляра здесь. Не имеет значения, какой тип переменной имеет его.

+0

Это не ошибка, но это немного вводит в заблуждение. Ссылка типа 'ProductA' * может * ссылаться на' FooProduct', но опять же, возможно, это не так. Вот почему актерский состав является законным, но может быть неудачным во время выполнения. –

+0

В частности, вы не можете четко различать ссылки и экземпляры. –

+0

Привет @Steven. Я не уверен, где я не понимаю; Я говорю, что вопрос, а не ссылка (переменная), в конечном итоге имеет значение. Если вы сможете объяснить, я отредактирую свое сообщение соответствующим образом. –

2

Довольно просто, когда ты удручен, что может или не может добиться успеха, вам нужно использовать is/as операторы, чтобы проверить, если экземпляр ProductA действительно MyProduct:

MyProduct myProduct = productAobject as MyProduct; 
if (myProduct != null) { 
    //valid MyProduct instance 
} else { 
    //productAobject is not really an instance of MyProduct 
} 
+1

Несомненно, если отказ не был исключением, в этом случае лучший оператор литья. –

Смежные вопросы