c# - 通用克隆实例

标签 c# generics

我想使用 CloneInstance 方法创建接口(interface),该方法返回该实例的通用类。例如:

public interface ICloneableExtended<T> where T : this
{
    T CloneInstance();
}

public class Car : ICloneableExtended
{
   ...
   ...

   public Car CloneInstance()
   { .. }
}

Foo()
{
   Car car ...;
   var clonedCar = car.CloneInstance();
}

在类的定义中Car , 我只需要使用 ICloneableExtended , 不是 ICloneableExtended<T> .有什么方法可以做到这一点吗?

最佳答案

您可以接受一个通用的 T将实现 ICloneableExtended 的具体类的参数:

interface ICloneableExtended<T> {
    Clone();
}

class Car : ICloneableExtended<Car> {
    public Car Clone() {
        throw new NotImplementedException();
    }
}

你可以考虑制作T参数协变(如果您希望保留 ICloneableExtended<Car> 与许多具体类 - 将实现 ICloneableExtended<T> ):

interface ICloneableExtended<out T> {
    Clone();
}

请注意,您可能不需要无通用 界面,您已经有了ICloneable (及其所有缺点和误用):

interface ICloneableExtended<out T> : ICloneable {
    Clone();
}

对于二进制可序列化类型,您甚至可以实现一个基本且可重用(但效率很低)的基类:

interface ICloneableExtended<T> : ICloneable {
    T Clone();
}

abstract class Cloneable<T> : ICloneableExtended<T> {
    public virtual T Clone() {
        using (var ms = new MemoryStream()) {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, this);

            ms.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(ms);
        }
    }

    object ICloneable.Clone() {
        return Clone();
    }
}

sealed class Car : Cloneable<Car> { }

使用这种方法,每个具体类都必须实现 ICloneableExtended<T>但你不能重载 Clone()方法只区分返回值那么你最好实现ICloneableExtended<T>明确地。一个不那么令人困惑的方法(对于谁实现这个接口(interface)以及谁将使用它)是提供一个扩展方法:

static class Extensions {
    public static T Clone<T>(this object obj) {
        var cloneable = obj as ICloneable;
        if (cloneable != null)
            return (T)cloneable.Clone();

        using (var ms = new MemoryStream()) {
            return (T)...
        }
    }
}

(为了清楚起见,我在这里使用 ICloneable,但如果您不想使用它,因为它在世界范围内随机使用,那么只需选择您自己的等效非通用接口(interface)即可)。

关于c# - 通用克隆实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33754866/

相关文章:

java - Scala 类 Final def this() 声明没有公共(public)无参构造函数

c# - 为什么编译器发出框指令来比较引用类型的实例?

c# - 仅调用泛型的基本方法

具有通用 self 类型的 Scala 特征

c# - 计算两个纬度和经度坐标之间的距离

c# - 在 WPF 中访问 XAML 控件

c# - 读取 CSV 到对象列表

c# - 从 cmdlet 中调用 Set-Location

c# - 为什么C#声明常量时不能使用匿名类型?

generics - 如何使用涉及泛型的匿名类型调用泛型方法?