2

次のシナリオを検討してください。

int Caller1<T>(T t) where T : IInterface {...}
T Caller2<T>() where T : IInterface {...}

class Wrappee // doesn't implement IInterface, but could

??? Wrapper : IInterface {
  private readonly Wrappee _wrappee;

  // methods call _wrappee's methods
}

structここで、とのどちらかを選択するための一般的なアドバイスは、 「値セマンティクスと参照セマンティクスが必要な場合にclass使用する」です。必要なセマンティクスは「への参照」です。しかし、まだ構造体を作成できるようです: その値をコピーすることは参照をコピーすることと同じであり、コピーは同じオブジェクトへの参照を持ちます! オーバーヘッドが低くなり、スカラー置換によってローカル変数のオーバーヘッドをゼロに減らすことができる場合があります。で変更メソッドを呼び出しても問題ないようです。structclassWrappeeWrapperWrappee_wrappee

何か不足していますか?Wrapper代わりにクラスを作成する正当な理由はありますか?

呼び出し元が一般的でない場合は、次の 1 つがあります。

int Caller(IInterface t) {...}

この場合Wrapper、ボクシングを避けるためのクラスにする必要があります。

Haskell を知っている人へのコメント: に最も近い .NET アナログを見つけようとしていますnewtype

更新:最初のケースでのボックス化の欠如については、MSDN フォーラムでProfessional .NET 2.0 GenericsPeter Ritchie を参照してください。

4

3 に答える 3

4

はい、IInterface 変数を介してラッパーにアクセスするため、ボックス化を回避するには、クラスにする必要があります。

編集: Wrapper として型指定された変数を介してラッパーにアクセスし、IInterface メソッドではなく Wrapper メソッドにアクセスする場合、構造体は問題ありません。

于 2009-07-31T18:03:43.627 に答える
2

多くの場合、クラス/構造体は、呼び出すメソッドによって内部的に格納または渡されます(Caller1とCaller2の機能は表示されませんでした)。その場合、おそらくボックス化されます。おそらくあなたが予想したよりも頻繁に。したがって、構造体がはるかに効率的であることを証明できない限り、わざわざクラスに固執しないでください。

さらに、構造体は、データ型のようなものを表していない限り、眉をひそめることがよくあります。そのため、クラスを選択すると、別の性質の将来の議論が妨げられる可能性があります。

ただし、パフォーマンスが本当に懸念事項であり、インスタンスがジェネリック型の制約を持つパラメーターとしてのみ渡され、インターフェイス型のフィールドまたはコレクションに格納されないことを保証できる場合、.NETランタイムによる構造体の現在のインライン化はラッパー構造体はほとんど最適化されるため、より効率的になります。しかし、それは多くの場合です。

于 2009-08-02T00:47:37.633 に答える
0

データだけでなく、動作をカプセル化しているため、クラスと言えます。

于 2009-07-31T18:03:19.447 に答える