C# 显式转换的问题
我在C#中有一个从另一个产品类继承的产品类C# 显式转换的问题,c#,inheritance,casting,C#,Inheritance,Casting,我在C#中有一个从另一个产品类继承的产品类 using ExternalAssemb.ProductA; public class MyProduct : ProductA { //.... } 我试图从ProductA中执行显式强制转换,它位于我引用的DLL中,但它告诉我它无法强制转换 MyProduct myProduct = (MyProduct)productAobject; 结果::System.InvalidCastException:无法将类型为“ExternalAs
using ExternalAssemb.ProductA;
public class MyProduct : ProductA
{
//....
}
我试图从ProductA中执行显式强制转换,它位于我引用的DLL中,但它告诉我它无法强制转换
MyProduct myProduct = (MyProduct)productAobject;
结果::System.InvalidCastException:无法将类型为“ExternalAssemb.ProductA”的对象强制转换为类型为“MyAssembly.MyProduct”
我做错了什么?您可以将ProductA
引用转换为MyProduct
引用,但前提是它实际上指向MyProductA
或其子项
你所做的是把父母当孩子一样对待,这是行不通的。相反,你可以像对待父母一样对待孩子,因为孩子就像父母一样
考虑一个通用示例,其中一个基类被称为Shape
,并且有子类,例如Square
和Circle
。给定一个形状
引用,您可以将任何子项指定给它。但是,如果引用引用的是圆
,则不能将其强制转换为正方形
。这是有道理的,因为所有的圆都是形状,但没有圆是正方形
希望这些例子能有所帮助 您可以将ProductA
引用强制转换为MyProduct
引用,但前提是它实际上指向MyProductA
或其子项
你所做的是把父母当孩子一样对待,这是行不通的。相反,你可以像对待父母一样对待孩子,因为孩子就像父母一样
考虑一个通用示例,其中一个基类被称为Shape
,并且有子类,例如Square
和Circle
。给定一个形状
引用,您可以将任何子项指定给它。但是,如果引用引用的是圆
,则不能将其强制转换为正方形
。这是有道理的,因为所有的圆都是形状,但没有圆是正方形
希望这些例子能有所帮助 每个MyProduct都是ProductA,但事实并非如此
productAobject
是ProductA的显式实例;这根本不是我的产品
同样,对于另一类:
public class FooProduct : ProductA
{
//....
}
…您不能这样做:
ProductA myFooProduct = new FooProduct();
MyProduct myProduct = (MyProduct)myFooProduct;
…因为FooProduct不是从MyProduct继承的
规则是:您只能将一个类的实例强制转换为它自己或它的一个祖先类。不能将其强制转换为继承树中的任何后代或任何其他同级/同级类
请记住,我们在这里讨论的是实例的实际类型。保存它的变量的类型无关紧要。每个MyProduct都是ProductA,但事实并非如此
productAobject
是ProductA的显式实例;这根本不是我的产品
同样,对于另一类:
public class FooProduct : ProductA
{
//....
}
…您不能这样做:
ProductA myFooProduct = new FooProduct();
MyProduct myProduct = (MyProduct)myFooProduct;
…因为FooProduct不是从MyProduct继承的
规则是:您只能将一个类的实例强制转换为它自己或它的一个祖先类。不能将其强制转换为继承树中的任何后代或任何其他同级/同级类
请记住,我们在这里讨论的是实例的实际类型。持有它的变量类型无关。很简单,当你向下转换时,可能成功,也可能失败,你需要使用
is/as
操作符来检查ProductA
的实例是否真的是MyProduct
:
MyProduct myProduct = productAobject as MyProduct;
if (myProduct != null) {
//valid MyProduct instance
} else {
//productAobject is not really an instance of MyProduct
}
很简单,当您向下转换时(可能成功,也可能失败),您需要使用
is/as
操作符来检查ProductA
的实例是否真的是MyProduct
:
MyProduct myProduct = productAobject as MyProduct;
if (myProduct != null) {
//valid MyProduct instance
} else {
//productAobject is not really an instance of MyProduct
}
或者如果为
ProductA
@zerkms实现了显式强制转换操作符:这是真的,但它也是与自然继承不同的东西。没有什么能阻止我让Aardvark
定义对Building
的显式转换,但这与Aardvark实际上是建筑没有任何关系。相反,Aarvark
实例必须返回一个Building
实例,很可能是通过创建一个实例。简而言之,它看起来像铸造,但实际上不是铸造。如果我将MyProduct铸造到ProductA,我如何获得MyProduct属性。我每次都必须这样做吗?((MyProduct)ProductA).MyProductProperty.@user204588:如果您获取一个MyProduct
实例并将其保存在ProductA
引用中,那么您只能将其视为ProductA
。如果您需要MyProduct
的任何特殊属性,则必须向下转换。但是,如果使用虚拟,则可以通过父级调用,但可以通过子级获得实现。@zerkms:完全正确。转换很好,但可能有损。将long
转换为int
时,可能会丢失部分原始值。事实上,这就是为什么转换是显式的,而int
到long
的转换是隐式的。或者如果为ProductA
@zerkms实现了显式强制转换操作符:这是真的,但它也是与自然继承不同的事情。没有什么能阻止我让Aardvark
定义对Building
的显式转换,但这与Aardvark实际上是建筑没有任何关系。相反,Aarvark
实例必须返回一个Building
实例,很可能是通过创建一个实例。简而言之,它看起来像铸造,但实际上不是铸造。如果我将MyProduct铸造到ProductA,我如何获得MyProduct属性。我每次都必须这样做吗?((MyProduct)ProductA).MyProductProperty.@user204588:如果您获取一个MyProduct
实例并将其保存在ProductA
引用中,那么您只能将其视为ProductA
。如果您需要MyProduct
的任何特殊属性,则必须向下转换。但是,如果使用虚拟,则可以通过父级调用,但可以通过子级获得实现。@zerkms:完全正确。转换很好,但可能有损。当你皈依