如何使用 ICloneable当 T 是 List 时?
我有以下内容:
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>> {}
但我得到了一个编译器错误。错误消息指出
列表<实例>
必须可转换为
ICloneable
为了在通用接口中使用参数 T
>
ICloneable
。
我在这里缺少什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您不能这样做,因为您无法自己定义
List
。由于您限制ICloneable
的方式,您只能声明自己的List
才能执行此操作。由于List
确实没有实现ICloneable
,因此您必须将 T 的类型改为 InstanceList,拥有控制权。以下是实现它的方法:
当然,您还可以采用另一种选择。您可以稍微拓宽您的泛型,以创建一个
CloneableList
类型:如果您真的想要变得更奇特,请创建一些将 T 限制为 ICloneable 的类型。然后,您可以在 Instance 类上实现 ICloneable,以及您想要包含在
ICloneable
列表中的任何其他内容,从而以完全相同的方式对待每个CloneableList
方式,避免为您想要创建的每个可克隆列表使用不同的ICloneable
实现。You can't do this, because you can't define
List<T>
yourself. You would only be able to do this if you could declare your ownList<T>
because of the way you've constrainedICloneable<T>
. SinceList<T>
truly doesn't implementICloneable<T>
, you're going to have to have the type of T be InstanceList instead, which you do have control over.Here's how you would implement it:
Of course, there is another alternative you could do. You could widen your generics a little bit, to create a
CloneableList<T>
type:And if you really want to get fancy, create something that restricts T to ICloneable. Then you could implement ICloneable on the Instance class, and anything else you want to include in an
ICloneable<T>
list, thus treating everyCloneableList<T>
in the exact same way, avoiding a different implementation ofICloneable<T>
for each and every cloneable list you want to create.问题是您的通用约束
where T : IClonable
。因为您将界面“实例化”为ICloneable
,>
List
是您的T
,所以通用约束转换为where List; :IClonable<列表<实例>
。List
不满足该约束。也许你正在尝试做这样的事情:
The problem is your generic constraint
where T : IClonable<T>
. Because you're "instantiating" your interface asICloneable<List<Instance>>
,List<Instance>
is yourT
, and so the generic constraint translates towhere List<Instance> : IClonable<List<Instance>>
.List<Instance>
does not fulfill that constraint.Perhaps you're trying to do something like this:
添加到已经存在的其他好的答案 - 当你克隆时,你希望得到一个相同的副本,对吧?因此,而不是:
实际上不应该是:
这样你也不会得到编译器错误。
To add to the other good answers already there - when you clone, you expect to get an identical copy back, right? So instead of:
Shouldn't it actually be:
That way you will also get no compiler errors.
我不认为你真的能做你想做的事。虽然不需要 ICloneable 的类型参数是有用的,但要实现 ICloneable,我不认为 List类可以很好地扩展以支持克隆,因为它不提供任何分离或复制保存所有数据项的数组的方法,不允许子类访问该数组,并且不允许子类重写足够的虚拟方法使数组变得无关。尽管克隆方法应该从使用 MemberwiseClone 开始(以确保克隆的对象与原始对象的类型相同),但没有保证的方法可以强制新克隆的列表创建一个新数组来保存其对象而不干扰旧的对象一。
我可以建议做你想做的最接近的事情是定义一个 ICloneableList它继承自 IList;和 ICloneable>并定义一个 CloneableList 类,它通过包装列表来实现它。克隆 CloneableList 应该创建一个新的 List包含从旧列表复制的项目,这可以通过使用新列表的适当构造函数来完成。
I don't think you can really do what you want. While it is useful not to require the type argument of ICloneable<T> to implement ICloneable<T>, I don't think the List<T> class can be very well extended to support cloning since it does not provide any means of detaching or duplicating the array which holds all the data items, does not allow a subclass access to that array, and does not allow a subclass to override enough virtual methods to render the array irrelevant. Although clone methods should start by using MemberwiseClone (to ensure that the cloned object is the same type as the original), there would be no guaranteed way to force the newly-cloned list to create a new array to hold its objects without disturbing the old one.
The closest thing I can suggest to doing what you want would be to define an ICloneableList<T> which inherits from IList<T> and ICloneable<IList<T>> and define an CloneableList class which implementats that by wrapping a list. Cloning a CloneableList should create a new List<T> with items copied from the old one, which can be done by using the appropriate constructor for the new List.