Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用iClonable<;T>;当T为列表时<;T>;?_C#_Icloneable - Fatal编程技术网

C# 如何使用iClonable<;T>;当T为列表时<;T>;?

C# 如何使用iClonable<;T>;当T为列表时<;T>;?,c#,icloneable,C#,Icloneable,我有以下资料: public class InstanceList : List<Instance> {} public interface ICloneable<T> : ICloneable Where T : ICloneable<T> { new T Clone(); } public class InstanceList : List<Instance>, IClone

我有以下资料:

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

    public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}
public类InstanceList:List{}
我想让这个克隆化。下面的示例如下:

我尝试了以下方法:

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

    public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}
公共接口ICloneable:ICloneable其中T:ICloneable
{new T Clone();}
公共类实例列表:列表,ICloneable{}
但是我得到了一个编译器错误。错误消息指出
列表
必须可转换为
ICloneable
为了在通用接口中使用参数T
ICloneable


我在这里遗漏了什么?

问题是您的通用约束
其中T:IClonable
。因为您正在将接口“实例化”为
IClonable
List
是您的
T
,因此通用约束转换为
其中List:IClonable
<代码>列表不满足该约束

也许你正在尝试这样做:

public interface ICloneableList<T> : ICloneable where T : ICloneable
{
}
公共接口ICloneableList:ICloneable其中T:ICloneable
{
}

您不能这样做,因为您不能定义自己的
列表。如果您可以声明自己的
列表
,则您只能这样做,因为您限制了
ICloneable
。由于
List
确实没有实现
ICloneable
,因此您必须使用t be 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();
}
公共类实例列表:列表,可克隆
{
公共实例列表克隆()
{
//在这里实现克隆勇气。
}
对象ICloneable.Clone()
{
返回((ICloneable)this.Clone();
}
}
公共类实例
{
}
公共接口ICloneable:ICloneable,其中T:ICloneable
{
新T克隆();
}
当然,你还可以做另一种选择。您可以稍微扩展泛型,以创建
CloneableList
类型:

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();
}
公共类可克隆列表:列表,可克隆
{
公共克隆列表克隆()
{
抛出新的InvalidOperationException();
}
对象ICloneable.Clone()
{
返回((ICloneable)this.Clone();
}
}
公共接口ICloneable:ICloneable,其中T:ICloneable
{
新T克隆();
}
如果你真的想变得更花哨,那就创造一些限制T不可克隆的东西。然后,您可以在实例类上实现ICloneable,以及希望包含在
ICloneable
列表中的任何其他内容,从而以完全相同的方式处理每个
CloneableList
,避免对要创建的每个可克隆列表使用不同的
ICloneable

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();
}
公共类可克隆列表:列表,可克隆,其中T:ICloneable
{
公共克隆列表克隆()
{
var result=新克隆列表();
result.AddRange(this.Select(item=>(T)item.Clone());
返回结果;
}
对象ICloneable.Clone()
{
返回((ICloneable)this.Clone();
}
}
公共接口ICloneable:ICloneable,其中T:ICloneable
{
新T克隆();
}

添加到其他已经存在的好答案中-当您克隆时,您希望得到相同的副本,对吗?因此,不是:

public class InstanceList : List<Instance>, ICloneable<List<Instance>>  {}
public类InstanceList:List,ICloneable{}
这不应该是:

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

这样,您也不会得到任何编译器错误。

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


我能建议做的最接近您想要做的事情是定义一个从IList和ICloneable继承的ICloneableList,并定义一个CloneableList类,该类通过包装一个列表来实现。克隆克隆可克隆列表应该创建一个新列表,其中包含从旧列表复制的项,这可以通过为新列表使用适当的构造函数来完成。

这很有效。一个变化:T克隆();需要新关键字来覆盖object.Clone()。我现在明白我的想法是错误的。我正在克隆类而不是列表。谢谢一定要查看我所做的编辑。第二个和第三个选项比我列出的第一个选项灵活得多。为什么它需要第二个对象ICloneable.Clone()方法?我认为这个接口只需要克隆()操作的一个方法。因为除了
ICloneable
,您还实现了ICloneable,所以需要第二个实现来满足ICloneable。它被称为“显式接口方法实现”,这基本上意味着,出于所有实际目的,它被认为是私有的,除非您使用“ICloneable”(不带T)类型持有对对象的引用,否则对“Clone()”方法的调用必须返回一个对象。请阅读以下内容:。基本上,您必须满足iClonable和
iClonable
。第三次编辑非常流畅。关于满足ICLONABLE要求的第二次覆盖的问题;为什么不简单地这样做:
object-ICloneable.Clone(){return-Clone();}
如果我这样做,我会得到'public-class-InstanceList:List,ICloneable{public-object-Clone(){}}'…然后返回