显式铸造有问题

时间:2010-08-15 23:07:00

标签: c# inheritance casting

我在C#中有一个继承自另一个产品类的产品类

using ExternalAssemb.ProductA;

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

我正在尝试从我引用的DLL中的ProductA进行显式转换,但它告诉我它无法投射

MyProduct myProduct = (MyProduct)productAobject;

Result :: System.InvalidCastException:无法将类型为“ExternalAssemb.ProductA”的对象强制转换为“MyAssembly.MyProduct”。

我做错了什么?

3 个答案:

答案 0 :(得分:5)

可以ProductA引用投射MyProduct引用,但如果它实际指向MyProductA或孩子。

你正在做的是试图像孩子一样对待父母,这是行不通的。相反,您可以将孩子视为父母,因为 就像父母一样。

考虑一个通用示例,其中基类被称为Shape并且具有诸如SquareCircle之类的子项。给定Shape引用,您可以为其分配任何子项。但是,如果引用引用Circle,则无法将其转换为Square。这是有道理的,因为所有圆都是形状,但没有圆是正方形。

希望这些例子有所帮助。

答案 1 :(得分: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 
}

答案 2 :(得分:1)

每个MyProduct也是ProductA,但反之则不然。 productAobject是ProductA的显式实例;它根本不是MyProduct。

同样,给另一个类:

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

......你不能这样做:

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

...因为FooProduct不从MyProduct继承。

规则是:您只能将类的实例强制转换为自身或其祖先类之一。您不能将其强制转换为继承树中的任何后代或任何其他兄弟/堂兄类。

请记住,我们在这里讨论实例的实际类型。保持它的变量的类型是无关紧要的。