2009-08-07 72 views
0

基本上我的設置是這樣的:是否有可以調整基類類型的返回類型的基類?

public abstract class BaseObject{ 
    public abstract BaseObject Clone(); 
} 

public class DerivedObject : BaseObject{ 
    public DerivedObject Clone() 
    { 
     //Clone logic 
    } 
} 

上面的代碼不編譯,因爲它不可能覆蓋方法時改變返回類型。

是否有可能實現每個派生類型的Clone方法返回它自己類型的參數(可能通過泛型)?

回答

3

嗯,C#不允許協變返回類型爲你找到......但你可以使用泛型:

public abstract class BaseObject<T> where T : BaseObject<T> 
{ 
    public abstract T Clone(); 
} 

public class DerivedObject : BaseObject<DerivedObject> 
{ 
    public override DerivedObject Clone() 
    { 
     // ... 
    } 
} 

該解決方案可以在各種方式的疼痛 - 這不僅是因爲這很難理解 - 但在很多情況下它可以很好地工作。

編輯:我在T上包含約束的原因是,BaseObject可以在T的實例上調用「它自己的」方法,這通常非常方便。如果你不需要這個,你可以失去約束。

+0

您能否描述一下這種解決方案可能會導致痛苦的各種方式? 我試圖找出是否值得采取這種痛苦的痛苦,而不必每次都使用克隆方法來強制轉換。 – chrischu 2009-08-07 20:37:38

+0

@Mehrdad:修正,謝謝。 @crischu:好吧,沒有什麼可以說另一個類不能從'BaseObject '派生的 - 因爲它不是萬無一失的。另外如果你必須與其他類型進行交互,它可以在協議緩衝區中獲得*真正*多毛* IMessage 其中TMessage:IMessage 其中TBuilder:IBuilder '例如。討厭。大多數都沒問題,但你需要保持冷靜的頭腦。 – 2009-08-07 20:40:35

0

你可以做這樣的事情。而不是返回默認(T),返回基於克隆邏輯的東西。

public class MyBase<T> 
{ 
    public T Clone() 
    { 
     return default(T); 
    } 
} 

public class MyDerived : MyBase<MyDerived> 
{ 
} 

順便說一句,對於對象克隆我喜歡使用二進制序列化序列化當前對象的內存,然後反序列化存儲回到一個新的實例。