将子对象转换为父对象

我需要能够将子对象的实例强制转换为父对象的实例。

public class Parent { public string name{get;set;} } public class Child : Parent{} var myClass = new Child() (Parent)myClass //this doesnt seem to work and the object still has childs type. 

是否有另一种方式来施展它?

谢谢

问题是xml serialiser将具有子类型的对象序列化为根元素。 我真的不想将目标类型一直传递给序列化器。 有没有更好的办法? – 朱尔斯

我没有多次使用序列化,但我的猜测是你需要改变你在子元素中“我如何序列化自己”的定义,把它自己写出来就像是父母一样。

如果你想要实际拥有“父”的实例,那么你需要创建一个新的Parent并将Child中的所有值复制到该Parent。 (如果你有很多这样的话,我不会这样做,但是如果你没有那么多,那么它应该不是问题。)最简单的方法是在Parent中创建一个复制构造函数。 它将是一个构造函数,它将Parent作为参数并将参数复制到自身的值(在这种情况下为Name,我假设您可能已省略其他值)。 然后你可以创建一个新的Parent,传入Child作为参数(因为Child是一个Parent,不需要强制转换/转换),它会吐出一个实际的Parent实例。

你没有将演员分配给任何东西。

 var myClass = new Child(); Parent p = (Parent)myClass; 

编辑 – 我认为你误解了铸造是如何工作的。 Say Parent有一个virtual方法, DoStuff()Child中被覆盖。 即使你将myClassParent ,它也会运行ChildDoStuff方法。 无论如何,即使你施展它, Child也是Child ,永远是Child

如果您尝试将其传递给接受Parent对象的方法,则不必强制转换它。 由于是一个Child ,它已经是Parent了。

我想我们错过了一些东西。 你还想尝试什么? 什么不起作用?

这应该工作。

但是我怀疑你编写代码的方式是不是在新变量中捕获了转换对象? 试试这个:

 var myClass = new Child() var myClassAsParent = (Parent)myClass; // myClassAsParent still has the type "Child", but can be accessed as if it were a Parent. 

编辑根据你一直留下的一些评论,我相信你误解了大多数编程语言的一个基本方面。 就是这样: 对象的类型不能改变 。 实例化为Child对象的对象始终是Child对象

转换不会更改对象的类型。 转换会改变程序其余部分“看到”对象的方式。 如果愿意,它会更改对象的界面。 因此,如果你将一个Child对象转换为Parent类型,那么程序的其余部分会认为它正在处理Parent类型,但它实际上处理的是Child类型,即使用一个非常糟糕的类比,用其父类的服装打扮。

简而言之,Casting不会按照您的想法行事。

你可以使用as运算符…好的事情是没有exception将被抛出,如果“强制转换”失败,你可以检查null。

 public class Parent { public string name{get;set;} } public class child : Parent{} var myClass = new Child() Parent foo = myClass as Parent if ( foo == null ) Debug.WriteLine("foo is NOT of type Parent"); 

如果ParentChild的超类,那么Child自动也是Parent (包含`Parent的所有属性和方法),您不需要强制转换。

此外,你不能只用一个演员开始一行。 你可以写一些例子

 Parent p = (Parent)myClass; 

刚刚遇到问题的变化,我想我已经有了一个非基于序列化的解决方案。

和OP一样,我有inheritance自A类的B类,我需要B.GetType()。返回的名称就像是A类一样。

在B类中,您需要重写GetType()以返回.GetType()。BaseType

那样B.GetType()总是看起来像A.GetType()

由于这是非常繁重的,并且我的所有类都inheritance自我自己的标准baseClass,因此我将向baseClass添加一个名为TypeName的属性,该属性返回this.GetType()。

然后在我想要看起来像它的父类的一个特殊类中,我将覆盖它以返回this.GetType()。BaseType.Name

然后在我的代码中,我将引用.TypeName而不是.GetType()。当我需要特殊的“掩盖”类的类型名称时,直接命名。假设我只使用.GetType()我需要忽略这个子类的一个区域,它对我自己的使用相当干净。

我遇到了同样的问题并提出了以下解决方案:

我的初始代码是这样的:

 public class Person { public string Name { get; set; } public Person() {}; public Person( Person rhs ) { Name = rhs.Name; } } public class Customer : Person { private string m_role = "Customer"; public string Role { get m_role; } public Customer() : base(); } public class Employee : Person { private string m_role = "Employee"; public string Role { get m_role; } public Customer() : base(); } 

当我尝试将一个Person对象转换为客户时,我遇到了“cast fail”错误

而不是追求铸造的想法,我决定修改Child的副本构造函数,因此:

 public class Customer : Person { private string m_role = "Customer"; public string Role { get m_role; } public Customer() : base(); public Customer( Person per ) : base( per); } public class Employee : Person { private string m_role = "Employee"; public string Role { get m_role; } public Employee () : base(); public Employee ( Person per) : base( per); } 

我在这里晚了五年,但……

您可以使用AutoMapper来解决您的问题。

只需定义父类和子类之间的映射。 最简单的地图就可以了。 在定义映射的类中:

 CreateMap(); 

然后,在代码中的任何位置,您都可以:

 Child child = new Child(); Parent parent = Mapper.Map(child); 

并且您的parent对象将是纯Parent ,没有child对象属性。

正如其他人所说,铸造一个物体将保留其类型。 那只会改变指针。 但AutoMapper会创建目标类型的新实例,并将值从参数复制到目标类型的实例,按名称匹配属性。