C# 将子对象转换为父对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9082011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
cast child object as parent
提问by Jules
I need to be able to cast an instance of a child object to an instance of the parent object.
我需要能够将子对象的实例转换为父对象的实例。
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.
is there another way to cast it?
有没有另一种方法来投射它?
thanks
谢谢
采纳答案by Servy
problem is the xml serialiser serialises the object with child type as root element. i dont really want to pass my target type all the way down into the serialiser. is there a better way? – Jules
问题是 xml 序列化器以子类型作为根元素序列化对象。我真的不想将我的目标类型一直传递到序列化程序中。有没有更好的办法?– 朱尔斯
I haven't worked with serialization much, but my guess is that you're going to need to alter your definition of "how do I serialize myself" in the child element to write itself out as if it was a parent.
我对序列化的工作不多,但我的猜测是,您将需要更改子元素中“我如何序列化自己”的定义,以将自己写出来,就好像它是父元素一样。
If you want to actually have and instance of "Parent" then you'll need to create a new Parent and copy all of the values from the Child to that Parent. (I wouldn't do this if you have a lot of them, but if you don't have thatmany then it shouldn't be a problem.) The easiest way to do this would be to make a copy constructor in Parent. It would be a constructor that take a Parent as a parameter and copies the values (Name in this case, and I assume you may have omitted others) from the parameter to itself. You can then make a new Parent, pass in the Child as the parameter (since a Child is a Parent, no cast/conversion is needed) and it will spit out an actual instance of Parent.
如果您想真正拥有“Parent”的实例,那么您需要创建一个新的 Parent 并将所有值从 Child 复制到该 Parent。(如果你有很多,我不会这样做,但如果你没有那么多,那么这应该不是问题。)最简单的方法是在 Parent 中创建一个复制构造函数。这将是一个构造函数,它将 Parent 作为参数并将值(在本例中为 Name,我假设您可能省略了其他参数)从参数复制到自身。然后,您可以创建一个新的父级,将子级作为参数传入(因为子级是父级,因此不需要强制转换/转换),它将吐出父级的实际实例。
回答by Matt Grande
You're not assigning the cast to anything.
您没有将演员表分配给任何东西。
var myClass = new Child();
Parent p = (Parent)myClass;
Edit- I think you misunderstand how casting works. Say Parent has a virtualmethod, DoStuff()that is overridden in Child. Even if you cast myClassto Parent, it's going to run the Child's DoStuffmethod. No matter what, that Childis a Child, and will always be a Child, even if you cast it.
编辑- 我认为你误解了铸造的工作原理。说 Parent 有一个virtual方法,DoStuff()在Child. 即使您转换myClass为Parent,它也会运行Child的DoStuff方法。无论如何,那Child是Child,并且永远是Child,即使你施放它。
If you're trying to pass it to a method that accepts a Parentobject, you don't have to cast it. It's already a Parent, by virtue of being a Child.
如果您尝试将其传递给接受Parent对象的方法,则不必强制转换它。Parent由于是,它已经是Child。
I think we're missing something. What are you trying to accoplish? What's not working?
我想我们错过了一些东西。你想完成什么?什么不工作?
回答by Muad'Dib
you could use the as operator... nice thing about THAT is no exception will be thrown and you can check for null if the "cast" fails.
您可以使用 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");
回答by Randolpho
That should work.
那应该工作。
But I suspect from the way you've written your code that you haven't captured the cast object in a new variable? Try this:
但我怀疑从您编写代码的方式来看,您没有在新变量中捕获强制转换对象?尝试这个:
var myClass = new Child()
var myClassAsParent = (Parent)myClass;
// myClassAsParent still has the type "Child", but can be accessed as if it were a Parent.
EditBased on some of the comments you've been leaving, I believe you misunderstand a fundamental aspect of most programming languages. It is this: the Type of an object cannot change. An object that was instantiated as a Childobject will always be a Childobject.
编辑根据您已经离开的一些评论,我相信您误解了大多数编程语言的一个基本方面。就是这样:对象的类型不能改变。实例化为Child对象的对象将始终是Child对象。
Casting does not change the type of an object. Casting changes the way the rest of the program "sees" the object. It changes the interface of the object, if you will. So if you cast a Childobject to a Parenttype, the rest of the program thinks it's dealing with a Parenttype, but it's reallydealing with a Childtype that is, to use a really bad analogy, dressed up in its parent's clothing.
转换不会改变对象的类型。投射改变了程序的其余部分“看到”对象的方式。如果您愿意,它会更改对象的接口。所以,如果你投一个Child对象的Parent类型,该程序的其余部分认为它在处理一个Parent类型,但它确实处理一个Child类型就是使用一个非常糟糕的比喻,在其父的服装打扮。
In short, Casting doesn't do what you think it does.
简而言之,Casting 不会做您认为它会做的事情。
回答by Karl Cassar
If Parentis a superclass of Child, then automatically a Childis also a Parent(contains all properties & methods of `Parent) and you don't need to cast.
如果Parent是 的超类Child,则自动 aChild也是 a Parent(包含`Parent 的所有属性和方法)并且您不需要强制转换。
Also, you cannot just start a line with a cast. You could write for example
此外,你不能只用演员表开始一行。你可以写例如
Parent p = (Parent)myClass;
回答by Ken Forslund
Having just hit a variation of the problem, I think I've got a non-serialization based solution.
刚刚遇到问题的一个变体,我想我有一个基于非序列化的解决方案。
Like the OP, I have Class B that inherits from Class A, and I need B.GetType().Name to return as if it was Class A.
像 OP 一样,我有从 A 类继承的 B 类,我需要 B.GetType().Name 返回,就好像它是 A 类一样。
On Class B, you need to override GetType() to return .GetType().BaseType
在 B 类上,您需要重写 GetType() 以返回 .GetType().BaseType
That way B.GetType() will always look like A.GetType()
这样 B.GetType() 将始终看起来像 A.GetType()
As that's rather heavy handed, and all my classes inherit from my own standard baseClass, I'm going to add a property called TypeName to the baseClass that returns this.GetType().Name
由于这相当繁琐,而且我的所有类都继承自我自己的标准 baseClass,因此我将向返回 this.GetType().Name 的 baseClass 添加一个名为 TypeName 的属性
Then on my one special class that I want to look like it's parent, I'll override it to return this.GetType().BaseType.Name
然后在我想要看起来像它的父类的一个特殊类上,我将覆盖它以返回 this.GetType().BaseType.Name
Then in my code, I'll reference .TypeName instead of doing .GetType().Name directly when I need the special "masking" of the class's type name to kick in. Given that I'm only using .GetType() in the one area where I need to ignore this child class, it's fairly clean for my own use.
然后在我的代码中,当我需要类的类型名称的特殊“屏蔽”来启动时,我将引用 .TypeName 而不是直接执行 .GetType().Name。鉴于我只使用 .GetType()我需要忽略这个子类的一个区域,它对于我自己的使用来说相当干净。
回答by Orcbighter
I had the same problem and came up with the following solution:
我遇到了同样的问题,并提出了以下解决方案:
My initial code was thus:
我的初始代码是这样的:
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();
}
and when I tried casting a Person object to a customer I got "cast fail" errors
当我尝试将 Person 对象转换为客户时,我收到了“转换失败”错误
Rather than pursuing the idea of casting I decided to modify the Child's copy constructors, thus:
我决定修改 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);
}
回答by Renan
I'm about five years late here, but...
我在这里晚了大约五年,但是......
You can use AutoMapperto solve your problem.
您可以使用AutoMapper来解决您的问题。
Just define a mapping between the parent and child classes. The simplest map will do. In the class where you define your mappings:
只需定义父类和子类之间的映射。最简单的地图就可以了。在定义映射的类中:
CreateMap<Child, Parent>();
Then, at any point in your code, you could do:
然后,在您的代码中的任何一点,您都可以执行以下操作:
Child child = new Child();
Parent parent = Mapper.Map<Parent>(child);
And your parentobject will be a pure Parentwith none of the childobject properties.
并且您的parent对象将是Parent没有任何child对象属性的纯对象。
As others have said, casting an object will preserve its type. That only changes the pointer. But AutoMapper creates a new instance of the target type and copies values from the parameter to the instance of the target type, matching properties by name.
正如其他人所说,投射对象将保留其类型。那只会改变指针。但是 AutoMapper 创建目标类型的新实例并将值从参数复制到目标类型的实例,按名称匹配属性。

