【发布时间】:2017-02-11 18:24:08
【问题描述】:
我正在尝试在抽象基类中实现ICloneable.Clone(),这样子类就不用担心了。
该类的一个基本职责是拥有一个应该传递给克隆的内部Guid 属性——也就是说,它更像是一个“属性克隆”。这允许我克隆从存储库中获取的项目,在不更改原始项目的情况下更改其属性,然后以它可以通过 Id 识别的方式将更改的实例提交回存储库。
但我当前的实现面临一个问题:我无法创建实例来传递 Id,因为该类是抽象的!
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设为抽象,因为子类会知道如何克隆自己。 -
@Luaan 你认为基于反射的方法可以吗?
-
@juharr 实际上,这可能是确保
Clone由派生类实现的最佳解决方案。仍然必须确保Clone被所有可以实例化的类覆盖。 -
当然,但是为什么要使用
ICloneable?只需创建一个可以克隆任何对象的通用辅助方法。如果您不想使用继承/多态,则将其作为基类的一部分是没有意义的。