Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.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 - Fatal编程技术网

C# 如何显式转换类型(自定义类)

C# 如何显式转换类型(自定义类),c#,inheritance,C#,Inheritance,我有下面的代码,我学习。我知道我不能隐式地将父母转换为子女,但我可以将父母转换为子女。但是,我尝试显式转换,但无法使其工作。我认为当转换为父级时,子级应该会丢失数据 class Parent { int A=5; } class Child:Parent { int B=5; int C=2; } Parent parent = new Parent(); Child ch = new Child(); ch=ch as Parent //or (Parent)ch

我有下面的代码,我学习。我知道我不能隐式地将父母转换为子女,但我可以将父母转换为子女。但是,我尝试显式转换,但无法使其工作。我认为当转换为父级时,子级应该会丢失数据

class Parent
{
    int A=5;
}

class Child:Parent
{
    int B=5;
    int C=2;
}

Parent parent = new Parent();
Child ch = new Child();

ch=ch as Parent //or (Parent)ch;
ch是父母,没有必要这样做

如果你测试这个表达式

bool isParent = ch is Parent

您将看到isParent=true。您可以在任何地方使用ch作为父级,而不使用任何强制转换

为什么需要这样做?由于继承关系,子对象是父对象。任何你需要父母的地方,你都可以传递一个孩子,这应该有效,如果不行,你就违反了法律

您可以将孩子视为父母,如下所示:

但这是毫无意义的

使用和的区别在于是否会出错。如果ch不是Parent的实例,那么使用as的“safe”强制转换只会给您留下null,在本例中,它总是这样。如果无法执行强制转换,另一个将抛出。

问题是ch是一个子对象,而您正试图为其分配一个父对象。你试过把最后一行换成新的吗

Parent pa = ch as Parent;
改变


将子对象强制转换为父对象,但结果是子对象

将最后一行修改为

Parent castRef = ch as Parent; 
Parent castRef = (Parent)ch;
前者是安全强制转换,它将检查ch是否实际上是的父类型或Decentant,如果是,则返回对父类的引用,如果不是,则返回null。如果ch是父对象,则这与as操作符是密切相关的

后者是一个显式的强制转换,不进行检查,通常会给您留下一个指向某个不属于父级或不属于父级的东西的引用,当您使用它时,该引用会出现异常错误

我总是喜欢前一个版本


并明确回答你的问题;您需要一个新的父类型变量ref来分配强制转换到。

强制转换时,您需要将类型设置为正确的类型

Child ch = child as Parent; //Wrong
Child ch = (Parent)child;   //Wrong
Parent p = child as Parent; //Correct
Parent p = (Parent)child;   //Correct
var p = child as Parent;    //Correct (var will end up being a Parent)
var p = (Parent)child;      //Correct (var will end up being a Parent)
这个问题可以解释不同类型的铸件

我认为当转换为父级时,子级应该会丢失数据

class Parent
{
    int A=5;
}

class Child:Parent
{
    int B=5;
    int C=2;
}

Parent parent = new Parent();
Child ch = new Child();

ch=ch as Parent //or (Parent)ch;

这是一个错误的假设。您没有丢失数据,但您正在更改类型,从而更改您可以访问的成员。将其更改回子级,成员B和C仍保留其值。

请注意对象实例和引用之间的差异

new Child();
实例化创建子类的实例。这意味着堆中现在有一个对象,但您没有对该对象的直接访问权,您可以通过对该对象的引用进行间接访问。对象实例化后,就不能更改其类型

Child ch;
定义一个具有子接口的引用,默认情况下该子接口不引用任何对象,即:null

Parent parent;
定义具有父接口的引用

一旦存在这些参照,就可以使用以下线条将其指定给对象:

parent = new Parent();

因为正如其他人所说,子对象继承自父对象,所以它是父对象,父对象引用也可以引用子对象。即:

parent = new Child();

但您将只能访问父对象通过父引用定义的子对象部分。请注意,此操作不需要强制转换。但是,您需要另一个方向的演员阵容。也就是说,如果它仍然是子对象,但到目前为止您只有父引用,则需要强制转换来获取子引用:

ch = (Child)parent;


如果无法执行强制转换,前者将引发异常。如果无法执行强制转换,则后者会将null分配给ch。

我假设子级在转换为父级时会丢失数据。不,你似乎对c语言中一些重要概念的工作方式有一些很糟糕的想法。我推荐Jon Skeet的书,深入阅读C,阅读msdn文档,并可能翻阅书面规范@asawyer谢谢,但是从double到int的转换呢?有数据丢失,这正是我的意思。double到int没有继承链。你在这里处理苹果和橙子,混合术语。
ch = new Child();
parent = new Child();
parent = ch;
ch = (Child)parent;
ch = parent as Child;