<T> 当 T 是列表时如何使用 <T>ICloneable?



我有以下内容:

    public class InstanceList : List<Instance> {}

我想让它可克隆。下面的例子是:为什么没有ICloneable?

我试了如下:

    public interface ICloneable<T> : ICloneable Where T : ICloneable<T>
           {        new T Clone();    }
    public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}

但是我得到一个编译错误。错误消息指出List<Instance>必须可兑换成ICloneable<List<Instance>>以便在泛型接口中使用参数TICloneable<T> .

我在这里错过了什么?

您不能这样做,因为您不能自己定义List<T>。如果您可以声明自己的List<T>,因为您约束ICloneable<T>的方式,您将只能这样做。由于List<T>确实没有实现ICloneable<T>,因此您将不得不将T的类型改为InstanceList,您确实可以控制它。

你可以这样实现它:

public class InstanceList : List<Instance>, ICloneable<InstanceList>
{
    public InstanceList Clone()
    {
        // Implement cloning guts here.
    }
    object ICloneable.Clone()
    {
        return ((ICloneable<InstanceList>) this).Clone();
    }
}
public class Instance
{
}
public interface ICloneable<T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

当然,还有另一种选择。您可以稍微扩展泛型,创建一个CloneableList<T>类型:

public class CloneableList<T> : List<T>, ICloneable<CloneableList<T>>
{
    public CloneableList<T> Clone()
    {
        throw new InvalidOperationException();
    }
    object ICloneable.Clone()
    {
        return ((ICloneable<CloneableList<T>>) this).Clone();
    }
}
public interface ICloneable<T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

如果你真的想变得更花哨,创建一些限制T为iclonable的东西。然后,您可以在Instance类上实现iclonable,以及您想要包含在ICloneable<T>列表中的任何其他内容,从而以完全相同的方式处理每个CloneableList<T>,避免为您想要创建的每个可克隆列表实现ICloneable<T>

public class CloneableList<T> : List<T>, ICloneable<CloneableList<T>> where T : ICloneable
{
    public CloneableList<T> Clone()
    {
        var result = new CloneableList<T>();
        result.AddRange(this.Select(item => (T) item.Clone()));
        return result;
    }
    object ICloneable.Clone()
    {
        return ((ICloneable<CloneableList<T>>) this).Clone();
    }
}
public interface ICloneable<T> : ICloneable where T : ICloneable<T>
{
    new T Clone();
}

问题是您的通用约束where T : IClonable<T>。因为您将接口"实例化"为ICloneable<List<Instance>>,所以List<Instance>是您的T,因此通用约束转换为where List<Instance> : IClonable<List<Instance>>List<Instance>不满足这个约束。

也许你正在尝试这样做:

public interface ICloneableList<T> : ICloneable where T : ICloneable
{
}

再加上其他已经存在的好答案——当你克隆时,你期望得到一个相同的副本,对吗?所以不是:

public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}

实际上不应该是:

public class InstanceList : List<Instance>, ICloneable<InstanceList>  {}

我不认为你真的能做你想做的事。虽然不需要iclonable的类型参数是有用的要实现ICloneable,我不认为List类可以很好地扩展以支持克隆,因为它不提供任何分离或复制包含所有数据项的数组的方法,不允许子类访问该数组,并且不允许子类重写足够的虚拟方法以使数组无关。虽然克隆方法应该首先使用MemberwiseClone(以确保克隆的对象与原来的对象类型相同),但是没有保证的方法可以强制新克隆的列表创建一个新数组来保存它的对象,而不干扰旧的数组。

我能建议的最接近你想做的事情是定义一个iclonablelist 继承自IList和ICloneable比;并定义一个cloneableelist类,它通过包装一个列表来实现。克隆CloneableList应该创建一个新的List<</p>

可以通过使用新List的适当构造函数来完成。

相关内容

  • 没有找到相关文章

最新更新