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