7

私はこのタイプのクラスを持っています:

class A<TResult>
{
     public TResult foo();
}

しかし、このクラスを非ジェネリック クラスとして使用する必要がある場合もあります。つまり、型TResultvoid.
次の方法でクラスをインスタンス化できません。

var a = new A<void>();

また、山かっこを省略して型を指定したくありません。

var a = new A();

同じことをするので、クラス全体を書き直したくありません。

4

4 に答える 4

8

FCLvoidに対応する構造体があっても、C# では実際の型ではありません。System.Void残念ながら、次のような非汎用バージョンが必要です。

class A
{
   //non generic implementation
}

class A<T> : A
{
   //generic implementation 
}

System.ActionFCL では、 の代わりに/とSystem.Action<T>の代わりに/があることがわかります。System.Action<void>TaskTask<void>

編集CLI仕様(ECMA-335)から:

次の種類の型は、(ジェネリック型またはメソッドの) インスタンス化で引数として使用できません。

Byref 型 (例: System.Generic.Collection.List`1<string&> は無効)

CIL 評価スタックを指すことができるフィールドを含む値の型 (例: List<System.RuntimeArgumentHandle>)

void (例: List<System.Void> は無効)

于 2012-10-26T08:23:30.820 に答える
4

コメントに投稿したように、ジェネリック クラスから継承することで見栄えを良くすることができます。

class A:A<object>
{
}

これによりジェネリック パラメータが明らかに隠されますが、私の経験では、これはクラスを継承する間違った方法であることに注意してください。これを行うたびに、クラスがより複雑になるにつれて後悔しました。

于 2012-10-26T08:34:51.910 に答える
1

voidはC#の型ではないため、型パラメーターとして使用することはできません。しかし、それでも、機能性が1つであるかのように機能したい場合があります。

この種の場合、単純な置換タイプを使用できます。ほとんどの場合、ReactiveExtensionsで使用されるSystem.Reactive.Unitなどの非常に小さな構造です。

于 2012-10-26T08:36:00.387 に答える
0

もう 1 つのオプション (falanwe が得たものと思われる) は、NullObject デザイン パターンを使用することです。 http://sourcemaking.com/design_patterns/null_object

于 2014-06-03T15:43:08.657 に答える