我有以下内容:
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
我能建议的最接近你想做的事情是定义一个iclonablelist