C# 如何在基类中创建对象的克隆?
我需要一个在基类中创建对象的空克隆的方法?例如:C# 如何在基类中创建对象的克隆?,c#,inheritance,C#,Inheritance,我需要一个在基类中创建对象的空克隆的方法?例如: 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 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();
}
有没有办法从父类执行此操作,这样我就不必为每个不同的子类实现相同的逻辑?请注意,可能有更多级别的继承(即ChildClass:ChildClass:ParentClass)。如果使用反射对您来说不是问题,您可以使用Activator类:
//In parent class
public ParentClass CreateEmpty()
{
return (ParentClass)Activator.CreateInstance(this.GetType());
}
这将返回所需类型的空对象。请注意,此方法不需要是虚拟的
另一方面,我认为您当前的方法非常好,没有几行代码那么糟糕。如果使用反射对您来说不是问题,您可以使用Activator类:
//In parent class
public ParentClass CreateEmpty()
{
return (ParentClass)Activator.CreateInstance(this.GetType());
}
这将返回所需类型的空对象。请注意,此方法不需要是虚拟的
另一方面,我认为您当前的方法非常好,很少有代码行不是那么糟糕。这有点实验性。我不知道这是否会导致循环依赖。已经好几个月没碰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() { }
}
公共类ParentClass,其中T:ParentClass,new(){//已修复
公共父类(){
var x=new T();//已修复,为T.new()
}
}
公共类子类:父类{
公共子类(){}
}
否则,选择Ravadre的ReflectionCode。这有点实验性。我不知道这是否会导致循环依赖。已经好几个月没碰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() { }
}
公共类ParentClass,其中T:ParentClass,new(){//已修复
公共父类(){
var x=new T();//已修复,为T.new()
}
}
公共类子类:父类{
公共子类(){}
}
否则,请使用Ravadre的ReflectionCode。您可以对该对象进行深度克隆
编辑:刚刚注意到克隆旁边的“空”字(我认为这是一个矛盾修饰法)。不管怎样,把这个回答留着,希望它能帮助其他人找到这个问题,因为他们正在寻找一个常规的克隆。你可以对这个对象进行深度克隆
编辑:刚刚注意到克隆旁边的“空”字(我认为这是一个矛盾修饰法)。不管怎样,把这个回答留着,希望它能帮助其他发现这个问题的人,因为他们正在寻找一个常规的克隆。我使用以下模式 优点:
- 此模式确保类的私有和公共端克隆的类型安全
- 输出类总是正确的
- 您永远不会忘记覆盖“克隆”方法。“MyDerivedClass”不会返回“MyDerivedClass”以外的其他类
- 对于一个类,您需要创建一个接口和两个类(prototype和final)
// 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
}
}
//可克隆类的公共接口。
公共接口IPrototype:可克隆{
新的IPrototype克隆();
}
//可克隆类的通用接口。
//“TFinal”最终是应克隆的类(类型)。
公共接口IPrototype,其中TFinal:IPrototype{
新的t最终克隆();
}
//可克隆类的基类。
//“TFinal”最终是应克隆的类(类型)。
公共抽象类PrototypeBase:IPrototype,其中TFinal:PrototypeBase{
公共TFinal克隆(){
TFinal ret=this.CreateCloneInstance();
if(null==ret){
抛出新的InvalidOperationException(“未创建克隆实例”);
}
这是一个很好的例子;
返回ret;
}
//如果重写,将创建新的克隆实例
受保护的抽象TFinal CreateCloneInstance();
//如果覆盖,请使用正确的值填充克隆实例。
受保护的抽象空填充克隆实例(t最终克隆);
IPrototype IPrototype.Clone(){返回this.Clone();}
对象ICLOnable.Clone(){返回此.Clone();}
}
//独立类的公共接口。
公共接口IMyStandaloneClass:IPrototype{
字符串SomeText{get;set;}
字符串SomeNumber{get;set;}
}
//prototype类包含克隆实例创建之外的所有功能。
公共抽象类MyStandaloneClassPrototype:PrototypeBase,IMyStandaloneClass,其中TFinal:MyStandaloneClassPrototype{
公共字符串SomeText{get;set;}
公共整数SomeNumber{get;set}
受保护的重写FillCloneInstance(t最终克隆){
//现在用值填充克隆
clone.SomeText=this.SomeText;
clone.SomeNumber=this.SomeNumber;
}
}
//密封的clas仅包含克隆实例创建功能。
公共密封类MyStandaloneClass:MyStandaloneClass原型{
受保护的覆盖MyStandaloneClass CreateCloneInstance(){
返回新的MyStandaloneClass();
}
}
公共接口IMYExtendedStatandLoneClass:IMYStandLoneClass,IPrototype{
日期时间{get;set;}
}
//MyStandaloneClassPrototype的扩展原型。
公共抽象类MyExtendedStandaloneClassPrototype:MyStandaloneClassPrototype其中TFinal:MyExtendedStandaloneClassPrototype{
公共日期时间{get;set;}
受保护的重写FillCloneInstance(t最终克隆){
//首先,填充基类成员
base.FillCloneInstance(克隆);
//现在用值填充克隆
clone.someone=this.someone;
}
}
公共密封类MyExtendedStandaloneClass:MyExtendedStandaloneClass原型{
受保护的重写MyExtendedStandaloneClass CreateCloneInstance(){
返回新的MyExtendedStandaloneClass
}
}
我正在使用以下模式
优点:
- 这