C# 为什么我的克隆代码不能编译?

C# 为什么我的克隆代码不能编译?,c#,interface,clone,C#,Interface,Clone,我有一个简单的克隆界面,我想使用。看起来它应该编译,但它没有。我收到一条消息说我的BObject类没有实现DeepClone。我不理解这一点,因为我有一个DeepClone方法,我的BObject类实现了IObject 我遇到的问题是,没有检查BObject.DeepClone方法是否返回一个BObject作为结果。我可以有这样一个类: class BObjectImposter : IObject { public string Name { get; set; } publi

我有一个简单的克隆界面,我想使用。看起来它应该编译,但它没有。我收到一条消息说我的BObject类没有实现DeepClone。我不理解这一点,因为我有一个DeepClone方法,我的BObject类实现了IObject

我遇到的问题是,没有检查BObject.DeepClone方法是否返回一个BObject作为结果。我可以有这样一个类:

class BObjectImposter : IObject
{
    public string Name { get; set; }
    public double Sales { get; set; }

    public IObject DeepClone()
    {
        //returns a BObject instead of a BObjectImposter
        return new BObject() { Name = this.Name, Sales = this.Sales };
    }
}
使用这个类,我可以写以下内容:

BObjectImposter objImp = new BObjectImposter();
IObject copy = objImp.DeepClone();
我可能认为copy是BObjectImposter的一个实现,但它实际上是一个不相关类BObject的实现,碰巧也实现了IObject。我理解接口的意义在于,我使用哪种实现并不重要,但对我来说,这似乎不是好代码。也许在我的BobObjectImposter实现中的某个地方,我希望DeepClone返回一个BobObjectImposter对象。另外,IOObject的一个实现不应该依赖于IOObject的另一个实现


也许我可以把IOObject变成一个抽象类,然后在那里声明DeepClone。如果有一个实现称之为ObjectA,我需要在构造函数中设置销售之前设置名称,另一个实现称之为ObjectB,我需要在构造函数中设置销售之前设置名称,这似乎可能会破坏我的设计。

正如您在问题中所暗示的,IOObject实现了IDeepClonable,所以它的DeepClone方法必须返回ioobject

您需要始终使用以下选项:

interface IObject<T> : IDeepCloneable<T> where T : IObject<T>
class BObject : IObject<BObject>

您还应该将where T:IDeepCloneable添加到IDeepCloneable

,正如您在问题中所暗示的,ioobject实现了IDeepClonable,因此它的DeepClone方法必须返回ioobject

您需要始终使用以下选项:

interface IObject<T> : IDeepCloneable<T> where T : IObject<T>
class BObject : IObject<BObject>

您还应该将where T:idepcloneable添加到idepcloneable

中,因为IObject继承了idepcloneable,所以DeepClone将返回一个IObject。以下方面应起作用:

    interface IDeepCloneable<T>
{
    T DeepClone();
}

interface IObject<T> : IDeepCloneable<T>
{
    string Name { get; }
    double Sales { get; }
}

//'BObject' does not implement interface member
//  'IDeepCloneable<IObject>.DeepClone()'
class BObject : IObject<BObject>
{
    public string Name { get; set; }
    public double Sales { get; set; }

    public BObject DeepClone()
    {
        return new BObject() { Name = this.Name, Sales = this.Sales };
    }
}

这是因为IObject继承了IDeepCloneable,所以DeepClone将返回一个IObject。以下方面应起作用:

    interface IDeepCloneable<T>
{
    T DeepClone();
}

interface IObject<T> : IDeepCloneable<T>
{
    string Name { get; }
    double Sales { get; }
}

//'BObject' does not implement interface member
//  'IDeepCloneable<IObject>.DeepClone()'
class BObject : IObject<BObject>
{
    public string Name { get; set; }
    public double Sales { get; set; }

    public BObject DeepClone()
    {
        return new BObject() { Name = this.Name, Sales = this.Sales };
    }
}

对于您的代码,如何使用接口?例如,此行给出一个错误:IObject a=新的BObject;表示IOObject需要1个类型参数。@user2023861:每个使用IOObject的方法都必须是泛型的。这种非常恼人的限制是存在的,因为C不支持更高级的类型。您可以使IObject在T中协变,这样您就可以始终使用IObject。对于您的代码,如何使用接口?例如,此行给出一个错误:IObject a=新的BObject;表示IOObject需要1个类型参数。@user2023861:每个使用IOObject的方法都必须是泛型的。这种非常恼人的限制是存在的,因为C不支持更高级的类型。你可以让IObject在T中协变,这样你就可以一直使用IObject。我该如何使用这些接口?此代码IObject a=新的BObject;给我一个错误,说IOObject需要1个类型参数。我可以使用IObject a=新的BObject;但这似乎打破了使用接口的想法。恐怕这就是静态类型的问题。您必须将返回类型参数传递到调用类/方法中。这是我认为微软从未将iClonable更新为通用的主要原因。我如何使用这些接口?此代码IObject a=新的BObject;给我一个错误,说IOObject需要1个类型参数。我可以使用IObject a=新的BObject;但这似乎打破了使用接口的想法。恐怕这就是静态类型的问题。您必须将返回类型参数传递到调用类/方法中。这是我认为微软从未将iClonable更新为通用的主要原因。