我需要能够将子对象的实例强制转换为父对象的实例。
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.
还有另一种投射方法吗?
感谢
答案 0 :(得分:11)
你没有将演员表分配给任何东西。
var myClass = new Child();
Parent p = (Parent)myClass;
编辑 - 我认为您误解了投射是如何运作的。假设父母有一个virtual
方法,DoStuff()
在Child
中被覆盖。即使您将myClass
投射到Parent
,它也会运行Child
的{{1}}方法。无论如何,DoStuff
都是Child
,并且永远都是Child
,即使你投了它。
如果您尝试将其传递给接受Child
对象的方法,则不必强制转换它。由于是Parent
,它已经是Parent
。
我认为我们错过了一些东西。你还想尝试什么?什么不起作用?
答案 1 :(得分:8)
这应该有效。
但我怀疑你编写代码的方式是否未在新变量中捕获转换对象?试试这个:
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不会按照您的想法行事。
答案 2 :(得分:7)
问题是xml serialiser将子类型的对象序列化为 根元素。我真的不想一直传递我的目标类型 进入序列化器。有没有更好的办法? - 朱尔斯
我没有多次使用序列化,但我的猜测是你需要改变你在子元素中“我如何序列化自己”的定义,把它自己写出来就像是父母一样。
如果你想要实际拥有“父”的实例,那么你需要创建一个新的Parent并将Child中的所有值复制到该Parent。 (如果你有很多这样的话,我不会这样做,但如果你没有 那么多,那么这应该不是问题。)最简单的方法是在Parent中创建一个复制构造函数。它将是一个构造函数,它将Parent作为参数并将参数复制到自身的值(在这种情况下为Name,我假设您可能已省略其他值)。然后你可以创建一个新的Parent,传入Child作为参数(因为Child是一个Parent,不需要强制转换/转换),它会吐出一个实际的Parent实例。
答案 3 :(得分:1)
你可以使用as运算符......好的事情就是抛出没有异常,如果“强制转换”失败,你可以检查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");
答案 4 :(得分:1)
如果Parent
是Child
的超类,则自动Child
也是Parent
(包含“父级”的所有属性和方法)需要施展。
此外,你不能只用一个演员开始一行。你可以写例如
Parent p = (Parent)myClass;
答案 5 :(得分:1)
刚刚遇到问题的变化,我想我已经有了一个非基于序列化的解决方案。
与OP一样,我有继承自A类的B类,我需要B.GetType()。返回的名称就像它是A类一样。
在B类中,您需要覆盖GetType()以返回.GetType()。BaseType
那样B.GetType()总是看起来像A.GetType()
由于这是非常繁重的,并且我的所有类都继承自我自己的标准baseClass,我将向baseClass添加一个名为TypeName的属性,该属性返回this.GetType()。Name
然后在我的一个特殊类中,我希望它看起来像是父类,我将覆盖它以返回this.GetType()。BaseType.Name
然后在我的代码中,我将引用.TypeName而不是执行.GetType()。当我需要特殊的“掩盖”类的类型名称时,直接命名。鉴于我只使用.GetType ()在我需要忽略这个子类的一个区域,它对我自己来说相当干净。
答案 6 :(得分:1)
我在这里已经晚了五年,但是......
您可以使用AutoMapper来解决问题。
只需定义父类和子类之间的映射。最简单的地图就可以了。在定义映射的类中:
CreateMap<Child, Parent>();
然后,在代码中的任何一点,您都可以:
Child child = new Child();
Parent parent = Mapper.Map<Parent>(child);
您的parent
对象将是纯Parent
,没有child
个对象属性。
正如其他人所说,投射对象将保留其类型。这只会改变指针。但AutoMapper会创建目标类型的新实例,并将值从参数复制到目标类型的实例,按名称匹配属性。
答案 7 :(得分:0)
我遇到了同样的问题并提出了以下解决方案:
我的初始代码是:
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 Employee() : base();
}
当我尝试将一个Person对象转换为客户时,我得到了#34;施放失败&#34;错误
而不是追求铸造的想法,我决定修改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);
}