假设我有一个抽象基类,我想要一个 CreateCopy
方法:
public abstract class BaseClass
{
///base stuff
public BaseClass CreateCopy() //or public object, if necessary
{
//?????
}
}
假设所有派生类都有一个无参数的构造函数和属性字段(可以)标记有某种属性:
public class DerivedClass : BaseClass
{
[CopiableProperty]
public string Property1 {get; private set;}
[CopiableProperty]
public int Property2 {get; private set;}
//no need to copy
public int Property3 {get; private set;}
//parameterless constructor
public DerivedClass() { }
}
是否可以使用此结构编写 CreateCopy()
的主体,以便我可以使用正确的 CopiableProperty
字段创建派生对象的新实例?
自然地,我可以制作一个public abstract BaseClass CreateCopy()
并强制每个派生类维护自己的副本,但是由于派生类的大小和数量,这会带来太多额外的努力。
最佳答案
一个相当简单的方法可能是使用泛型和反射:
public abstract class BaseClass
{
// restrict to children of BaseClass
public T CreateCopy<T>() where T: BaseClass, new()
{
var copy = new T();
// get properties that you actually care about
var properties = typeof(T).GetProperties()
.Where(x => x.GetCustomAttribute<CopiablePropertyAttribute>() != null);
foreach (var property in properties)
{
// set the value to the copy from the instance that called this method
property.SetValue(copy, property.GetValue(this));
}
return copy;
}
}
public class DerivedClass : BaseClass
{
[CopiableProperty]
public string Property1 { get; set; }
[CopiableProperty]
public int Property2 { get; set; }
public int Property3 { get; set; }
public override string ToString()
{
return $"{Property1} - {Property2} - {Property3}";
}
}
static void Main(string[] args)
{
var original = new DerivedClass
{
Property1 = "Hello",
Property2 = 123,
Property3 = 500
};
var copy = original.CreateCopy<DerivedClass>();
Console.WriteLine(original);
Console.WriteLine(copy);
Console.ReadLine();
}
这将打印:
Hello - 123 - 500
Hello - 123 - 0
另一种方法是利用序列化库,如果你不介意依赖的话:
public abstract class BaseClass
{
public BaseClass CreateCopy()
{
string serialized = JsonConvert.SerializeObject(this);
var actualType = GetType();
return JsonConvert.DeserializeObject(serialized, actualType) as BaseClass;
}
}
public class DerivedClass : BaseClass
{
public string Property1 { get; set; }
public int Property2 { get; set; }
[JsonIgnore]
public int Property3 { get; set; }
//parameterless constructor
public DerivedClass() { }
public override string ToString()
{
return $"{Property1} - {Property2} - {Property3}";
}
}
关于c# - 根据具有属性的属性复制派生类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51402258/