我需要一个在基类中创建对象的空克隆的方法吗?例如:
public class ChildClass : ParentClass
{
public ChildClass()
{
}
}
public class ParentClass
{
public SomeMethod()
{
// I want to create an instance of the ChildClass here
}
}
到目前为止,我们在父类中定义了一个抽象方法。并且,所有子类都实现它们。但是,实现对所有人来说都是一样的,只是一种不同的类型。
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();
}
有没有办法从父类中执行此操作,以便我不必为每个不同的子类继续实现相同的逻辑?请注意,可能有更多级别的继承(即ChildChildClass:ChildClass:ParentClass)。
答案 0 :(得分:5)
如果使用反射不是问题,可以使用Activator类:
//In parent class
public ParentClass CreateEmpty()
{
return (ParentClass)Activator.CreateInstance(this.GetType());
}
这将返回所需类型的空对象。请注意,此方法不需要是虚拟的。
另一方面,我认为您当前的方法非常好,几行代码并不是那么糟糕。
答案 1 :(得分:0)
这有点实验性。我不知道这是否会导致循环依赖。几个月没碰过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() { }
}
否则请去Ravadre的ReflectionCode。
答案 2 :(得分:0)
您可以对对象using the binary serializer进行深度克隆。
编辑:刚刚注意到克隆旁边的“空”这个词(我认为这是一个矛盾)。无论如何都要保留这个回复,希望它能帮助其他人找到这个问题,因为他们希望做一个普通的克隆。
答案 3 :(得分:0)
我使用以下模式。
<强>优点:强>
<强>缺点:强>
样品:
// 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
}
}