Беда с явным приведением - PullRequest
1 голос
/ 16 августа 2010

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

using ExternalAssemb.ProductA;

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

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

MyProduct myProduct = (MyProduct)productAobject;

Result :: System.InvalidCastException: невозможно преобразовать объект типа 'ExternalAssemb.ProductA' в тип 'MyAssembly.MyProduct'.

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

Ответы [ 3 ]

5 голосов
/ 16 августа 2010

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

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

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

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

2 голосов
/ 16 августа 2010

Проще говоря, когда вы понижаетесь, что может или не может быть успешным, вам нужно использовать 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 голос
/ 16 августа 2010

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...