如何解决无法从父级转换为子级的问题

本文关键字:转换 问题 何解决 解决 | 更新日期: 2023-09-27 18:32:52

我读过为什么你不能把父母交给孩子的原因:你不能把动物投给狗;它可能是一只猫。

但这是我的问题:

我从数据层接收一个包含 50 个属性的数据对象。现在我创建了此对象的子对象,只有一个属性。

在我的函数中,我想用基对象的 50 个属性和一个额外的属性填充对象的所有 51 个属性。

所以我正在寻找一种方法将父对象的 50 个属性"复制"到子对象。

有没有办法做到这一点?

如何解决无法从父级转换为子级的问题

这很可能是你不想使用继承的时候。 为此,新类型不会继承任何内容,并且具有两个属性,一个是旧类型(您当前正在考虑用作父类型),另一个是新数据。

您可以使用复制构造函数基于父对象创建新的子对象。 您甚至可以在父类中创建复制构造函数,并在创建新子类时使用该构造函数。

public Parent (Parent other)
{
   //copy other.Properties to this.Properties
}

public Child (Parent other) : base(other)
{
   //populate property 51
}
public Child (Child other) : base(other)
{
   //copy property 51
}

如果要将属性复制到现有实例,则可能需要为此创建单独的方法。

public void Assimilate(Parent other)
{
   //copy parent's properties
}
public void Assimilate(Child other)
{
   //copy child's properties
}

基于复制构造函数的通用解决方案有两种方法(即不涉及每个属性的手动复制和相关维护噩梦的方法):

  1. 使用反射制作浅拷贝。 这里的例子

  2. 使用序列化创建深层复制(将基本对象序列化为内存流,然后将该内存流序列化为派生对象)。此处示例的第一部分讨论序列化(本文讨论了这两种方法)。

这是

你的问题(复制构造函数答案似乎是一种可能的方法),但请注意,你可以从基类强制转换为子类,但它不能保证像从子类转换到基类那样成功。 见下文:

public class Base
{
}
public class Child1 : Base
{
}
public class Child2 : Base
{
}
main()
{
    Child1 ch1 = new Child1();
    Child2 ch2 = new Child2();
    Base myBase;
    myBase = ch1; // Always succeeds, no cast required
    myBase = ch2; // Always succeeds, no cast required
    // myBase contains ch2, of type Child2
    Child1 tmp1;
    Child2 tmp2;
    tmp2 = (Child2)myBase;   // succeeds, but dangerous
    tmp2 = mybase as Child2; // succeeds, but safer, since "as" operator returns null if the cast is invalid
    tmp1 = (Child1)myBase;   // throws a ClassCastException and tmp1 is still unassigned
    tmp1 = myBase as Child1; // tmp1 is now null, no exception thrown
    if(myBase is Child1)     
    {
        tmp1 = (Child1)myBase; // safe now, as the conditional has said it's true
    }
    if(myBase is Child2)     // test to see if the object is the sub-class or not
    {
        tmp2 = (Child2)myBase; // safe now, as the conditional has said it's true
    } 
}

我希望这是有道理的。 如果您只是盲目地投射它,它可能会引发异常。 如果使用 as 关键字,它将成功或返回 null。 或者,您可以在分配之前使用 if 语句和 is 关键字预先"测试"它。