0

据我所知,不建议实现ICloneable因为它不区分 Deep Copy 或 Shallow Copy),我正在尝试确定我应该将它实现为抽象还是接口。

我觉得我的实现将基本保持不变,例如二进制深拷贝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 {} 
4

2 回答 2

2

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

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 */ }
}
于 2013-08-05T18:32:38.480 回答
0

我在想创建一个界面是要走的路,但后来我发现了这个问题和第一个答案。这是进行克隆的好方法,但我认为使用自定义扩展方法可能会很好,所以我根据第一篇文章中的代码和 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>();
于 2013-08-05T20:34:49.050 回答