繁体   English   中英

C# 继承。 从基类派生类

[英]C# inheritance. Derived class from Base class

我有一个基类

public class A   
{
    public string s1;
    public string s2;
}

我也有一个派生类:

public class B : A
{
    public string s3;
}

假设我的程序创建了一个类 A 的实例。

A aClassInstance = new A();

设置了一些参数:

aClassInstance.s1 = "string 1";
aClassInstance.s2 = "string 2";

此时我想创建一个类 B 的实例。但我希望 B 已经拥有我的类 A 实例的值。

这不起作用:

public B bClassInstance = new B():
bClassInstance = (B)aClassInstance;

也没有这样做:

在 A 类中创建了一个克隆方法。

public B cloneA() {    
    A a = new A();
    a = (A)this.MemberwiseClone()
    return(B)a;
}

VS 代码采用上述两种方式 - 但我收到运行时错误

请帮忙

您遇到的基本问题是,您必须构造一个类型B的实例(其中包含类型A的属性)。 您克隆A实例的方法将不起作用,因为这为您提供了类型A的实例,您无法将其转换为B

我会为类 A 和 B 编写构造函数,它接受一个类型为 A 的参数。类 B 的构造函数只是将值传递给它的基类 A。类 A 的构造函数知道如何将字段复制到自身:

class A {
    public A(A copyMe) {
        s1 = copyMe.s1;
        ...
    }

class B : A {

    public B(A aInstance) : base(aInstance) {
    }

}

以这种方式使用它:

A a = new A();
a.s1 = "...";

B b = new B(a);

编辑

如果您不想在添加新字段或道具时更改A的构造函数,则可以使用反射来复制属性。 要么使用自定义属性来装饰要复制的内容,要么仅复制A所有道具/字段:

public A (A copyMe) {
    Type t = copyMe.GetType();
    foreach (FieldInfo fieldInf in t.GetFields())
    {
        fieldInf.SetValue(this, fieldInf.GetValue(copyMe));
    }
    foreach (PropertyInfo propInf in t.GetProperties())
    {
        propInf.SetValue(this, propInf.GetValue(copyMe));
    }
}

我还没有尝试过代码,但这一点应该很清楚。

您可以在类 A 中创建一个通用的克隆方法:

     public T Clone<T>() where T : A, new() {
          return new T() { a = this.a, b = this.b};
     }

或者,如果您想让克隆可扩展:

     public T Clone<T>() where T : A, new() {
          var result = new T();
          this.CopyTo(result);
          return result;
     }

     protected virtual void CopyTo(A other) {
          other.a = this.a;
          other.b = this.b;
     }

你像这样使用它:

     A  a = new A();
     // do stuff with a
     // Create a B based on A:
     B b = a.Clone<B>();

请注意:在您的示例中,new A() 和 MemberwiseClone 都将创建一个类型为 A 的新对象。

如果您不想自己编写复制方法的代码,则可以查看AutoMapper 之类的工具。

在四处玩耍并阅读我能看到的所有内容后,GvS 和 Jan 的上述两种解决方案都有效。 但是,我想要实现的最终结果不是被迫在 Copy 方法中写出每个成员。

为什么: a) 如果编辑了类并添加了另一个对象,则必须更新复制方法。 如果其他人更新了课程,他们可能会忘记这样做。

b) 可能有很多成员,分配他们可能很耗时。

c) 它只是“感觉”不对。 (可能是因为我很懒)。

幸运的是,我并不是唯一一个有同样想法的人。 通过 ValueInjector 找到了一个非常简单的解决方案。 (已经在这些板上讨论了很多)。

得到dll后(http://valueinjecter.codeplex.com/documentation)

代码变成:

A a = new A();
a.s1 = "...";


B b = new B();
b.InjectFrom(a);

而已 :)

显然,您必须包括:

using Omu.ValueInjecter;

并且不要忘记将其添加到参考文献中。

例如,您还可以使用 JSON 序列化程序。 您向子类添加一个静态方法,然后可以像这样调用它:

var porsche = Porsche.FromCar(basicCar);

这里,“Porsche”是子类,“Car”是基类。 该函数将如下所示:

public class Porsche : Car
{
    public static Porsche FromCar(Car basicCar)
    {
        // Create a JSON string that represents the base class and its current values.
        var serializedCar = JsonConvert.SerializeObject(basicCar);

        // Deserialize that base class string into the child class.
        return JsonConvert.DeserializeObject<Porsche>(serializedCar);
    }

    // Other properties and functions of the class...
}

这里的技巧是,在子项中可用但在基项中不可用的属性将使用其默认值创建,因此通常为 null,具体取决于属性的类型。 反序列化也按照属性的名称进行,因此所有属性都被复制。

我没有测试这段代码,但它应该可以工作,因为我以前做过一两次。 希望它可以帮助某人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM