实现自定义克隆/复制功能:抽象或接口



由于我了解到不建议实现ICloneable(因为它不区分深度复制和浅层复制),我正在尝试确定是将其实现为抽象还是接口。

我觉得我的实现在很大程度上保持不变,例如二进制深度拷贝和MemberwiseClone浅拷贝,所以为此,我觉得抽象方法将是理想的。然而,我的理解也是C#不做多重继承,因此,如果我需要使用另一个抽象类,那么我就不能再使用了。

在这种情况下,我觉得实现自定义ICloneable(例如ICustomCloneable)将是更好的选择,但如果实现在许多类中有效地相同,我觉得我没有充分利用代码重用。

话虽如此,在我的可克隆类中,使用接口来保持抽象继承的清晰性是否有效?或者有其他方法可以做到这一点吗?

或者,一个抽象实现另一个抽象有效吗?这将是我的猜测,以绕过阻止我实现CloneCapable类和另一个抽象的单一继承,但听起来可能有问题。例如:

public abstract class CloneCapable
{
  public object ShallowCopy()
  {
    // implementation
  }
  public object DeepCopy()
  {
    // implementation
  }
}
public abstract class ClassA : CloneCapable {}
// abstract-abstract since I can't do ClassB : ClassA, CloneCapable
public abstract class ClassB : ClassA {} 

我肯定会让它成为一个接口。原因是,接口应该是非常通用的,这就是为什么我们可以实现多个接口。如果你想编写一些锅炉板代码,那么没有什么可以阻止你同时利用接口和抽象类。

public interface ICustomCloneable<T>
{
    T ShallowCopy();
    T DeepCopy();
}
public abstract class CustomCloneable<T> ICustomCloneable<T> where T : class
{
    public T ShallowCopy() { return ShallowCopy(this); }
    public T DeepCopy() { return DeepCopy(this); }
    // static helpers
    public static object ShallowCopy(T obj) { /* boilerplate implementation */ }
    public static object DeepCopy(T obj) { /* boilerplate implementation */ }
}

public class ClassA : CustomCloneable<ClassA> { /* Use boilerplate functionality */ }
public class ClassB : SomeOtherClass, ICustomCloneable<ClassB>
{
    // implement ICustomCloneable using static helpers
    public ClassB ShallowCopy() { return CustomCloneable<ClassB>.ShallowCopy(this); }
    public ClassB DeepCopy() { return CustomCloneable<ClassB>.DeepCopy(this); }
}

我在这里使用了泛型,但没有理由你需要……甚至可能不需要。这种方法允许你编写样板代码,但不受其约束:

public class ClassC : ICustomCloneable<ClassC>
{
    public ClassC ShallowCopy() { /* Do special cloning for ClassC */ }
    public ClassC DeepCopy() { /* Do special cloning for ClassC */ }
}

我原以为创建一个接口是最好的方法,但后来我发现了这个问题和第一个答案。这是一个很好的克隆方法,但我认为这可能与自定义扩展方法配合得很好,所以我根据第一篇文章和MS帮助页面上的代码编写了闲置代码:

一些类可以玩:

[Serializable]
public abstract class Base
{
    public abstract int m1();
}
[Serializable]
public class derived : Base
{
    public int a = 42;
    public override int m1()
    {
        throw new NotImplementedException();
    }
}

基于两个链接的代码样本的具有扩展方法的类

//Extension methods must be defined in a static class 
public static class StringExtension
{
    // This is the extension method. 
    // The first parameter takes the "this" modifier
    // and specifies the type for which the method is defined. 
    public static T MyCloneExtension<T>(this T t)
    {
        // Code in this function was copied from https://stackoverflow.com/questions/78536/deep-cloning-objects-in-c-sharp
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }
        // Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(t, null))
        {
            return default(T);
        }
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, t);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }
}

最后是克隆对象的调用

derived d = new derived();
derived d2 = d.MyCloneExtension<derived>();

相关内容

  • 没有找到相关文章

最新更新