首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当T为List<T>时如何使用ICloneable<T>?

当T为List<T>时如何使用ICloneable<T>?
EN

Stack Overflow用户
提问于 2011-08-03 02:43:14
回答 4查看 7.1K关注 0票数 5

我有以下几点:

代码语言:javascript
复制
    public class InstanceList : List<Instance> {}

我想让它成为可克隆的。遵循这里的示例:Why no ICloneable?

我尝试了以下几种方法:

代码语言:javascript
复制
    public interface ICloneable<T> : ICloneable Where T : ICloneable<T>
           {        new T Clone();    }

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

但是我得到了一个编译器错误。错误消息指出,为了在通用接口ICloneable<T>中使用参数T,List<Instance>必须可转换为ICloneable<List<Instance>>

这里我漏掉了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-03 02:49:22

您不能这样做,因为您不能自己定义List<T>。由于约束ICloneable<T>的方式,只有在声明自己的List<T>时才能做到这一点。由于List<T>确实没有实现ICloneable<T>,所以您必须将T的类型改为InstanceList,这是您可以控制的。

下面是如何实现它的方法:

代码语言:javascript
复制
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>类型:

代码语言:javascript
复制
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限制为ICloneable的东西。然后,您可以在Instance类上实现ICloneable,以及您希望包含在ICloneable<T>列表中的任何其他内容,从而以完全相同的方式对待每个CloneableList<T>,从而避免为您想要创建的每个可克隆列表使用不同的ICloneable<T>实现。

代码语言:javascript
复制
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();
}
票数 4
EN

Stack Overflow用户

发布于 2011-08-03 02:48:16

问题出在您的通用约束where T : IClonable<T>。因为您要将接口“实例化”为ICloneable<List<Instance>>,所以List<Instance>是您的T,因此泛型约束转换为where List<Instance> : IClonable<List<Instance>>List<Instance>不能满足这一限制。

也许你正在尝试这样做:

代码语言:javascript
复制
public interface ICloneableList<T> : ICloneable where T : ICloneable
{
}
票数 2
EN

Stack Overflow用户

发布于 2011-08-03 02:59:34

除了已经有的其他好答案--当你克隆时,你希望得到一个完全相同的副本,对吧?因此,不是:

代码语言:javascript
复制
public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}

它不应该是:

代码语言:javascript
复制
public class InstanceList : List<Instance>, ICloneable<InstanceList>  {}

这样一来,您也不会遇到编译器错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6916956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档