2009-08-07 4 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に制約を含めた理由は、Tのインスタンスでは、 "独自の"メソッドを呼び出すことができるので、通常は非常に便利です。あなたがこれを必要としない場合、あなたは制約を失うことができます。

+0

この解決策が痛みを伴う可能性があるさまざまな方法のいくつかを説明できますか? 私は、Cloneメソッドを使用するたびに型キャストする必要がないという苦痛を軽減するために、この苦痛を払う価値があるかどうかを判断しようとしています。 – chrischu

+0

@Mehrdad:固定、ありがとう。 @crischu:もう一つのクラスが 'BaseObject 'から派生することができないとは言いません。 IMessage ここで、TMessage:IMessage ここで、TBuilder:IBuilder は、他のタイプとやり取りする必要がある場合、例えば、不快な。それはほとんど大丈夫ですが、あなたはクールな頭を保つ必要があります。 –

0

このようなことができます。デフォルト(T)を返す代わりに、複製ロジックに基づいて何かを返します。ところで

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

public class MyDerived : MyBase<MyDerived> 
{ 
} 

、オブジェクトクローニングのために私は戻って新しいインスタンスにそのメモリをデシリアライズ次いで、バイナリシリアライザを使用して、メモリに現在のオブジェクトをシリアル化したいです。

関連する問題