2016-10-03 50 views
-2

我想在抽象基類中實現ICloneable.Clone(),以便子類不需要擔心它。 該類的基本職責是擁有應該傳遞給克隆的內部Guid屬性 - 也就是說,它更像是「屬性克隆」。這允許我克隆從存儲庫獲取的項目,在不更改原始項目的情況下更改其屬性,然後將已更改的實例以可以通過Id識別它的方式提交回回購。將抽象基類中的自定義ICloneable實現

但是我目前的實現面臨一個問題:我無法創建實例來傳遞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; 
    } 
} 

有沒有辦法解決這個問題?這是一個體面的設計開始嗎?

+2

無論如何,您正在創建錯誤的類型。問題是,你不知道什麼類型的基類應該在基類中。您需要創建實際運行時類型的實例 - 例如通過派生類將要實現的抽象方法。 – Luaan

+1

你可能只是做'克隆'抽象,因爲子類是知道如何克隆自己的。 – juharr

+0

@Luaan你認爲基於反思的方法會做什麼? – heltonbiker

回答

3

退後一步。 你不應該在所有的上實現這個接口,所以不管這個實現是在基類中還是在其他地方。首先,不要去那裏。

此接口已經自2003年見棄用:

Why should I implement ICloneable in c#?

瞭解詳情。

+0

嗯,我認爲這足夠autorostic; o)謝謝! – heltonbiker

0

正如評論已經解釋的,你不能這樣做......

做的最好的事情是可能使Clone一個抽象方法(以確保克隆可用於所有派生類雖然一個有明確覆蓋Clone如果更多的是一個級別的推導和更多的一個級別有一個class可以instanciated。)。

之後,有一種拷貝構造函數是要走的路:我不知道,如果我得到virtualoverride權利,我很少寫這樣的代碼

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; 
}