CLR:コンストラクターが失敗した場合、常に例外がスローされますか?
-
20-08-2019 - |
質問
Delphi では、オブジェクトの構築中に例外が発生した場合:割り当てられたメモリはすべて解放され、例外がスローされます。例えば次のような感じでした 保証されています 有効な値を返すか、 Camera
オブジェクトを返すか、例外をスローします。
Camera c = new Camera();
あなた 一度もない 結果の変数が null かどうかを確認する必要がありました。
Camera c = new Camera();
if (c == null)
throw new Exception("Error constructing Camera") //waste of time
CLRでも同じでしょうか?
また、戻り値が有効であるか、例外をスローすることが保証されている構文構造は他にもありますか?
- 構造の作成 (例:矩形)?
- 列挙のメンバーを取得するには?
- Object.ToString() の結果は?
- 数学的な操作?
数学を実行する場合:
Int32 aspect = 1650.0 / 1080.0;
if (aspect == null)
throw new Exception("Division of two numbers returned null")
解決
.Net のコンストラクターは、オブジェクトの型の null 以外のインスタンスを返すことが保証されています。インスタンスがあるかどうか 有効 型の個々のセマンティクスに依存します。
コンストラクターでスローされた例外は、CLR によって任意に飲み込まれることはありません (ただし、ユーザー コードが例外を飲み込むことはできます)。CLR は、他のメソッドでスローされた例外と同じように例外を伝播し、オブジェクトは最終的に適切にガベージ コレクションされます。
あなたが言及した他のケースについては、
- 構造の作成:定義上、構造体を null にすることはできません。コンストラクターでスローされた例外は通常どおり伝播します。
- 列挙型のメンバーを取得します。列挙型は内部では構造体/値型であり、null になることはありません
- Object.ToString() の結果:これは null になる可能性があります (そして残念なことに、null になります)。String は参照型であり、ToString オーバーライドから null を返すことは完全に合法です (やめてください)。
- 数学的演算:これは、プロジェクトのオーバーフロー設定と、使用されている特定の型 (整数型と整数型) の両方に大きく依存します。浮動小数点)。
数学的な質問は、ほとんどそれ自体で答えられるに値します。一方で、プリミティブ型に対する数学的演算の結果が null になることはありません。ただし、それでも無効になる可能性があります。たとえば、次のコードはスローされませんが、結果が有効かどうかは特定のシナリオに大きく依存します。
float f1 = 1.0;
float f2 = f1 / 0;
この時点で、f2 は実数を表さない非常に特殊な浮動小数点値です。有効ですか?ユースケースによって異なります。
他のヒント
はい。コンストラクタが例外をスローしない場合は、戻り値はあることが保証されています(ががの、あまりにもの論理的な失敗を意味するかもしれない失敗のように)私はこのようにそれを入れたいのですが非null
あなたは、このようなチェックを実行する必要はありませんので。
の作成構造(例えば矩形):struct
が全くnull
することができない(Nullable
タイプは即ちtypeof(int?) != typeof(int)
、完全に異なるタイプであると考えられます)。例外をスローすることによって失敗するか、インスタンスを返すのいずれかの構造のためのコンストラクタを呼び出します。
列挙のメンバーを取得:enum
は、定数のセットだけです。以下のように何もありません「実行時にメンバーを取得しては。」これは、コンパイル時に置換します。
Object.ToString()
の結果:いずれの方法と同様に、それはstring
を含み、また、例外をスローする可能性がnull
タイプの任意の有効な値を返すことができる(この場合、それは、すべての値を返さない)
数学演算:すべての式が値を返すか、例外をスローします。戻り値は(例えばInt32
がnull
することはできません)、その型の有効な値にすることができます。