構造体をクラスにブラインド変換してデフォルトのコンストラクターを非表示にしますか?

StackOverflow https://stackoverflow.com/questions/1429495

質問

このトピックに関連するすべての質問を読み、C#でstructのデフォルトコンストラクターが利用できない理由をすべて説明しますが、直面したときに一般的なアクションコースを提案する人はまだ見つかりませんこの状況。

明らかな解決策は、単にclassIsValidに変換し、その結果に対処することです。

internalとして保持する他のオプションはありますか?

社内コマースAPIオブジェクトの1つでこの状況に遭遇しました。デザイナーはそれを<=>から<=>に変換し、デフォルトのコンストラクター(以前はプライベートだった)がオブジェクトを無効な状態のままにします。

オブジェクトを<=>として保持する場合、状態の有効性をチェックするメカニズム(<=>プロパティのようなもの)を導入する必要があると考えました。私は多くの抵抗に遭い、<!> quot;の説明は、APIを使用する人は誰でもデフォルトのコンストラクタ<!> quotを使用すべきではありません。間違いなく私の眉を上げたコメント。 (注:問題のオブジェクトは、静的ファクトリーメソッドを介して<!> quot; properly <!> quot;で構築され、他のすべてのコンストラクターは<=>です。)

この状況で、誰もが簡単に<=> sを<=> esに変換しますか?

編集:このタイプのオブジェクトを<=>として保持する方法について、いくつかの提案を見たいと思います-上記の問題のオブジェクトは、<=>としてよりも<=>としてより適しています。

役に立ちましたか?

解決

structの場合、デフォルトで構築されたインスタンス(フィールドがすべてゼロ)が有効な状態になるようにタイプを設計します。正当な理由がない限り、classの代わりに<=>をarbitrarily意的に使用しない[ ]ことはできません。不変の参照型を使用しても問題はありません。

私の提案:

  • <=>を使用する理由が有効であることを確認します([実際の]プロファイラーにより、非常に軽量なオブジェクトの大量割り当てに起因する重大なパフォーマンス問題が明らかになりました)。
  • デフォルトで構築されたインスタンスが有効になるように型を設計します。
  • 型の設計がネイティブ/ COM相互運用制約によって規定されている場合、機能をラップし、ラッパーの外側に<=>を公開しないでください(プライベートな入れ子型)。そうすれば、制約された型の要件の適切な使用を簡単に文書化して検証できます。

他のヒント

この理由は、構造体(System.ValueTypeのインスタンス)がCLRによって特別に処理されるためです。すべてのフィールドが0(またはデフォルト)で初期化されます。実際に作成する必要はありません。宣言するだけです。これがデフォルトのコンストラクタが必要な理由です。

次の2つの方法でこれを回避できます。

  1. IsValidなどのプロパティを作成して、指定したように有効な構造体であるかどうかを示します
  2. .Net 2.0では、Nullable <!> lt; T <!> gt;の使用を検討してください。初期化されていない(null)構造体を許可します。

構造体をクラスに変更すると、いくつかの非常に微妙な結果(マルチスレッド環境でより多く発生するメモリ使用量とオブジェクトIDの点で)が発生する可能性があります。 / p>

デフォルトのコンストラクタを定義する可能性がない理由は、次の式で示されます:

new MyStruct[1000];

ここには3つのオプションがあります

  1. デフォルトのコンストラクタを1000回呼び出す、または
  2. 破損したデータの作成(構造体に参照を含めることができることに注意してください。参照を初期化または空白にしないと、任意のメモリにアクセスできる可能性があります)、または
  3. (バイトレベルで)ゼロで割り当てられたメモリを空にします。

.NETは、構造体とクラスの両方で同じことを行います。フィールドと配列要素はゼロで空白にされます。これにより、構造体とクラス間でより一貫した動作が得られ、安全でないコードもなくなります。また、.NETフレームワークがnew byte[1000]

のようなものを特化しないようにすることもできます。

それは、.NETが要求する構造体のデフォルトのコンストラクタであり、それ自体を処理します。すべてのバイトをゼロにします。

今、これを処理するために、いくつかのオプションがあります:

  • Am-I-Initializedプロパティを構造体に追加します(HasValueNullableなど)。
  • ゼロ化された構造体が有効な値になるようにします(0は10進数の有効な値です)。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top