C#继承.来自Base类的派生类

Sam*_*Sam 16 c# polymorphism inheritance

我有一个基类

public class A   
{
    public string s1;
    public string s2;
}
Run Code Online (Sandbox Code Playgroud)

我也有一个派生类:

public class B : A
{
    public string s3;
}
Run Code Online (Sandbox Code Playgroud)

假设我的程序创建了A类的实例.

A aClassInstance = new A();
Run Code Online (Sandbox Code Playgroud)

设置了一些参数:

aClassInstance.s1 = "string 1";
aClassInstance.s2 = "string 2";
Run Code Online (Sandbox Code Playgroud)

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

这不行:

public B bClassInstance = new B():
bClassInstance = (B)aClassInstance;
Run Code Online (Sandbox Code Playgroud)

没有这个:

在A类中制作克隆方法

public B cloneA() {    
    A a = new A();
    a = (A)this.MemberwiseClone()
    return(B)a;
}
Run Code Online (Sandbox Code Playgroud)

VS代码采用上述两种方法 - 但我得到了运行时错误

请帮忙

Jan*_*Jan 28

您遇到的基本问题是,您必须构造一个类型的实例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) {
    }

}
Run Code Online (Sandbox Code Playgroud)

用这种方式:

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

B b = new B(a);
Run Code Online (Sandbox Code Playgroud)

编辑

如果您不想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));
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有尝试过代码,但重点应该是明确的.


GvS*_*GvS 9

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

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

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

     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;
     }
Run Code Online (Sandbox Code Playgroud)

你这样使用它:

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

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

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