Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 显式转换的问题_C#_Inheritance_Casting - Fatal编程技术网

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

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

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:完全正确。转换很好,但可能有损。当你皈依