[英]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.