7

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

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

それをとして維持する他のオプションはありますstructか?

内部コマースAPIオブジェクトの1つでこの状況に遭遇しました。設計者はそれをaclassからに変換しましstructた。デフォルトのコンストラクター(以前はプライベートでした)は、オブジェクトを無効な状態のままにします。

オブジェクトをとして保持する場合structは、状態の妥当性をチェックするメカニズム(IsValidプロパティのようなもの)を導入する必要があると思いました。私は多くの抵抗に直面し、「APIを使用する人は誰でもデフォルトのコンストラクターを使用すべきではない」という説明に、確かに眉をひそめました。(注:問題のオブジェクトは静的ファクトリメソッドを介して「適切に」構築され、他のすべてのコンストラクターはinternalです。)

structこの状況では、誰もが考え直すことなく、単に自分のsをclassesに変換しているのでしょうか。

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

4

3 に答える 3

4

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

私の提案:

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

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

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

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

構造体をクラスに変更すると、(マルチスレッド環境でより多く発生するメモリ使用量とオブジェクトIDに関して)非常に微妙な結果が生じる可能性があり、初期化されていないオブジェクトのNullReferenceExceptionsをデバッグするのはそれほど微妙ではありません。

于 2009-09-15T20:45:56.450 に答える
0

デフォルトのコンストラクターを定義できない理由は、次の式で示されます。

new MyStruct[1000];

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

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

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

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

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

  • Am-I-Initializedプロパティを構造体に追加します(のようHasValueNullable)。
  • ゼロ化された構造体が有効な値になるようにします(0は小数の有効な値のように)。
于 2009-09-15T21:18:54.620 に答える