[英]How do I create clone of object in base class?
I need a method that creates an empty clone of an object in a base class? 我需要一个在基类中创建对象的空克隆的方法吗? For instance:
例如:
public class ChildClass : ParentClass
{
public ChildClass()
{
}
}
public class ParentClass
{
public SomeMethod()
{
// I want to create an instance of the ChildClass here
}
}
Up until now, we have an abstract method defined in the parent class. 到目前为止,我们在父类中定义了一个抽象方法。 And, all of the child classes implement them.
并且,所有子类都实现它们。 But, the implementation is the same for all, just a different type.
但是,所有实现都相同,只是类型不同。
public class ChildClass : ParentClass
{
public ChildClass()
{
}
public ParentClass CreateEmpty()
{
return new ChildClass();
}
}
public class ParentClass
{
public SomeMethod()
{
// I want to create an instance of the ChildClass here
ParentClass empty = CreateEmpty();
}
public abstract ParentClass CreateEmpty();
}
Is there any way to do this from the parent class so that I don't have to keep implementing the same logic for each different child class? 有什么办法可以从父类中做到这一点,这样我就不必继续为每个不同的子类实现相同的逻辑? Note that there may be more levels of inheritance (ie ChildChildClass : ChildClass : ParentClass).
注意,可能会有更多级别的继承(即ChildChildClass:ChildClass:ParentClass)。
If using reflection isn't a problem to you, you could do it using Activator class: 如果使用反射对您来说不是问题,则可以使用Activator类来实现:
//In parent class
public ParentClass CreateEmpty()
{
return (ParentClass)Activator.CreateInstance(this.GetType());
}
This will return empty object of the type you want. 这将返回所需类型的空对象。 Notice that this method does not need to be virtual.
请注意,此方法不必是虚拟的。
On the other hand, I think that your current approach is perfectly fine, few more lines of code aren't so bad. 另一方面,我认为您当前的方法还不错,再多几行代码也不错。
This is somewhat experimental. 这有点实验。 I don't know whether this will lead to a cyclic dependency.
我不知道这是否会导致循环依赖。 Haven't touched C# for some months.
几个月没有接触C#。
public class ParentClass<T> where T : ParentClass<T>, new() { // fixed
public ParentClass() {
var x = new T(); // fixed, was T.new()
}
}
public class ChildClass : ParentClass<ChildClass> {
public ChildClass() { }
}
Otherwise go for the ReflectionCode by Ravadre. 否则,请使用Ravadre的ReflectionCode。
You can make a deep clone of the object using the binary serializer . 您可以使用二进制序列化程序对对象进行深层克隆。
EDIT: Just noticed the word "empty" next to clone (which I thought was an oxymoron). 编辑:刚注意到克隆(我认为是矛盾的意思)旁边的单词“空”。 Leaving this response up anyhow hoping it will help others that find this question because they are looking to do a regular clone.
不管怎样,不要把这个答案留给别人,因为其他人希望进行常规克隆,这将有助于他们找到这个问题。
I'm using the following pattern. 我正在使用以下模式。
Pros: 优点:
Cons: 缺点:
Sample: 样品:
// Common interface for cloneable classes.
public interface IPrototype : ICloneable {
new IPrototype Clone();
}
// Generic interface for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public interface IPrototype<TFinal> where TFinal : IPrototype<TFinal> {
new TFinal Clone();
}
// Base class for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public abstract class PrototypeBase<TFinal> : IPrototype<TFinal> where TFinal : PrototypeBase<TFinal> {
public TFinal Clone() {
TFinal ret = this.CreateCloneInstance();
if ( null == ret ) {
throw new InvalidOperationException( "Clone instance was not created." );
}
this.FillCloneInstance( ret );
return ret;
}
// If overriden, creates new cloned instance
protected abstract TFinal CreateCloneInstance();
// If overriden, fill clone instance with correct values.
protected abstract void FillCloneInstance( TFinal clone );
IPrototype IPrototype.Clone() { return this.Clone(); }
object ICloneable.Clone() { return this.Clone(); }
}
// Common interface for standalone class.
public interface IMyStandaloneClass : IPrototype<IMyStandaloneClass> {
string SomeText{get;set;}
string SomeNumber{get;set;}
}
// The prototype class contains all functionality exception the clone instance creation.
public abstract class MyStandaloneClassPrototype<TFinal> : PrototypeBase<TFinal>, IMyStandaloneClass where TFinal : MyStandaloneClassPrototype<TFinal> {
public string SomeText {get; set;}
public int SomeNumber {get; set}
protected override FillCloneInstance( TFinal clone ) {
// Now fill clone with values
clone.SomeText = this.SomeText;
clone.SomeNumber = this.SomeNumber;
}
}
// The sealed clas contains only functionality for clone instance creation.
public sealed class MyStandaloneClass : MyStandaloneClassPrototype<MyStandaloneClass> {
protected override MyStandaloneClass CreateCloneInstance() {
return new MyStandaloneClass();
}
}
public interface IMyExtendedStandaloneClass : IMyStandaloneClass, IPrototype<IMyExtendedStandaloneClass> {
DateTime SomeTime {get; set;}
}
// The extended prototype of MyStandaloneClassPrototype<TFinal>.
public abstract class MyExtendedStandaloneClassPrototype<TFinal> : MyStandaloneClassPrototype<TFinal> where TFinal : MyExtendedStandaloneClassPrototype<TFinal> {
public DateTime SomeTime {get; set;}
protected override FillCloneInstance( TFinal clone ) {
// at first, fill the base class members
base.FillCloneInstance( clone );
// Now fill clone with values
clone.SomeTime = this.SomeTime;
}
}
public sealed class MyExtendedStandaloneClass : MyExtendedStandaloneClassPrototype<TFinal> {
protected override MyExtendedStandaloneClass CreateCloneInstance() {
return new MyExtendedStandaloneClass
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.