2011-06-28 15 views
1

は、私は、オブジェクトの種類を返すリクエストを処理し、次の一般的なクラスを持っている:C#は汎用パラメータとしてvoidを使用できないという事実を回避するには?

class Request<T> { 
    /* ... */ 

    public T Result { get; protected set; } 
    public abstract bool Execute(); 
    protected bool ExecuteCore(params /* ... */) { /* ... */ } 
} 

class ObjectRequest<T> : Request<T> 
    where T : class, new() { /* ... */ } 

class ListRequest<T> : Request<List<T>> 
    where T : class, new() { /* ... */ } 

class CompoundRequest<T, U> : Request<T> 
    where T : class, IHeader<U>, new() 
    where U : class, new() { /* ... */ } 

class CompoundRequest<T, U, V> : Request<T> 
    where T : class, IHeader<U>, IHeader<V>, IHeader<W>, new() 
    where U : class, new() 
    where V : class, new() { /* ... */ } 

class CompoundRequest<T, U, V, W> : Request<T> 
    where T : class, IHeader<U>, IHeader<V>, new() 
    where U : class, new() 
    where V : class, new() 
    where W : class, new() { /* ... */ } 

interface IHeader<T> { 
    List<T> Details { get; set; } 
} 

今私はオブジェクトを返さない要求を処理するクラスを作成したいと思います。ただし、汎用パラメータをnullに設定することはできません。

class NoReturnRequest : Request<void> { /* ... */ } // illegal 

この問題を回避するにはどうすればよいですか。

答えて

8

デザインパターンを反転させることをおすすめします。最初に何も返さない非generic Requestクラスを作成し、からを継承すると、Request<T>Request<T1, T2>Request<T1, T2, T3>などのクラスを継承します。値を返すクラス。

+0

@Adam:これは、Liskovの置換原理を破ります。 – pyon

+1

@Eduardo私は正直に反対しなければならない。あなたはこれをどう思いますか? –

+0

@アダム:それは私の質問から続くわけではありませんが、私があなたのアプローチに従えば私のクラスが実装される方法に従います。 LSPを壊すか、または2回実装する必要のある機能があります。 – pyon

0

汎用パラメータは、型付きパラメータに使用されます。パラメータに型がない場合は、別のクラスのインターフェイスまたは抽象クラスを使用します(リクエストも継承します)

1

これは、C#などの言語の機能が向上するにつれてよくある問題です。

RxチームはUnitを導入して解決しました。

関連する問題