将自定义 ICloneable 实现放在抽象基础中 class
Putting custom ICloneable implementation in abstract base class
我正在尝试在抽象基础 class 中实现 ICloneable.Clone()
,这样子classes 就不用担心了。
class 的基本职责是有一个内部 Guid
属性 应该传递给克隆 - 也就是说,它更像是 "property clone"。这使我可以克隆从存储库中获取的项目,更改其属性而不更改原始项目,然后将更改后的实例以可以通过 Id 识别的方式提交回存储库。
但是我当前的实现面临一个问题:我无法创建实例来传递 Id,因为 class 是抽象的!
public abstract class RepoItem : ICloneable, IEquatable<RepoItem>
{
protected RepoItem()
{
Id = Guid.NewGuid();
}
private RepoItem(Guid id)
{
Id = id;
}
public Guid Id { get; private set; }
public object Clone()
{
return new RepoItem(Id); // cannot create instance of abstract class
}
public bool Equals(RepoItem other)
{
return other.Id == Id;
}
}
有没有办法克服这个问题?这是一个体面的设计吗?
如评论中所述,您不能这样做...
最好的办法可能是使 Clone
成为一个抽象方法(以确保克隆对所有派生的 类 可用,尽管如果不止一层派生,还有一层有一个可以实例化的class
。)。
在那之后,拥有某种复制构造函数将是可行的方法:
class RepoItem : ICloneable
{
public abstract void Clone();
protected RepoItem(RepoItem other) { Id = other.Id; }
}
class Derived1 : RepoItem
{
protected Derived1(Derived1 other) : base(other)
{
myField1 = other.myField1;
}
public virtual object Clone() { return new Derived1(this); }
private int myField1;
}
class Derived2 : Derived1
{
protected Derived2(Derived2 other) : base(other)
{
myField2 = other.myField2;
}
public override object Clone() { return new Derived2(this); }
private int myField2;
}
我不确定我的 virtual
和 override
是否正确,因为我很少写这样的代码。
退一步。 你根本不应该实现这个接口,所以实现是在基础class中还是其他完全不重要的地方。一开始就不要去那里。
此接口自 2003 年以来已被弃用。请参阅:
Why should I implement ICloneable in c#?
了解详情。
我正在尝试在抽象基础 class 中实现 ICloneable.Clone()
,这样子classes 就不用担心了。
class 的基本职责是有一个内部 Guid
属性 应该传递给克隆 - 也就是说,它更像是 "property clone"。这使我可以克隆从存储库中获取的项目,更改其属性而不更改原始项目,然后将更改后的实例以可以通过 Id 识别的方式提交回存储库。
但是我当前的实现面临一个问题:我无法创建实例来传递 Id,因为 class 是抽象的!
public abstract class RepoItem : ICloneable, IEquatable<RepoItem>
{
protected RepoItem()
{
Id = Guid.NewGuid();
}
private RepoItem(Guid id)
{
Id = id;
}
public Guid Id { get; private set; }
public object Clone()
{
return new RepoItem(Id); // cannot create instance of abstract class
}
public bool Equals(RepoItem other)
{
return other.Id == Id;
}
}
有没有办法克服这个问题?这是一个体面的设计吗?
如评论中所述,您不能这样做...
最好的办法可能是使 Clone
成为一个抽象方法(以确保克隆对所有派生的 类 可用,尽管如果不止一层派生,还有一层有一个可以实例化的class
。)。
在那之后,拥有某种复制构造函数将是可行的方法:
class RepoItem : ICloneable
{
public abstract void Clone();
protected RepoItem(RepoItem other) { Id = other.Id; }
}
class Derived1 : RepoItem
{
protected Derived1(Derived1 other) : base(other)
{
myField1 = other.myField1;
}
public virtual object Clone() { return new Derived1(this); }
private int myField1;
}
class Derived2 : Derived1
{
protected Derived2(Derived2 other) : base(other)
{
myField2 = other.myField2;
}
public override object Clone() { return new Derived2(this); }
private int myField2;
}
我不确定我的 virtual
和 override
是否正确,因为我很少写这样的代码。
退一步。 你根本不应该实现这个接口,所以实现是在基础class中还是其他完全不重要的地方。一开始就不要去那里。
此接口自 2003 年以来已被弃用。请参阅:
Why should I implement ICloneable in c#?
了解详情。