29

変数が実行時にプログラムで初期化されているかどうかを確認したい。この不可解な理由を少なくするために、次の不完全なコードを参照してください。

string s;

if (someCondition) s = someValue;
if (someOtherCondition) s = someOtherValue;

bool sIsUninitialized = /* assign value correctly */;

if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s.");

そして、関連するビットを完成させます。

ハッキーな解決策の 1 つは、 s をデフォルト値で初期化することです。

string s = "zanzibar";

そして、変更されたかどうかを確認します。

bool sIsUninitialized = s == "zanzibar";

しかし、もしもsomeValuesomeOtherValueザンジバル」だったら?次に、バグがあります。もっと良い方法はありますか?

4

8 に答える 8

25

コンパイラが変数が初期化されていないことを認識している場合、コードはコンパイルされません。

string s;
if (condition) s = "test";
// compiler error here: use of unassigned local variable 's'
if (s == null) Console.Writeline("uninitialized");

それ以外の場合default、変数が初期化されていない可能性がある場合は、キーワードを使用できます。たとえば、次の場合です。

class X
{ 
    private string s;
    public void Y()
    {
        Console.WriteLine(s == default(string));  // this evaluates to true
    }
}

ドキュメントnullには、 default(T) が参照型と値型に与えると記載されてい0ます。コメントで指摘されているように、これは null のチェックとまったく同じです。


nullこれはすべて、変数が最初に宣言されたときに、 変数を実際に初期化する必要があるという事実を覆い隠しています。

于 2012-09-13T20:05:05.230 に答える
11

C# 2.0 では、Nullable 演算子を使用して、これまでの値型に対して null の初期値を設定できるようになり、次のようなことが可能になります。

int? x = null;

if (x.HasValue)
{
    Console.WriteLine("Value for x: " + num.Value); 
}

これは、「x の値: Null」を生成します。

于 2012-09-13T20:09:34.937 に答える
7

null文字列値ではなく、デフォルトで割り当てるだけです

于 2012-09-13T20:07:40.933 に答える
3

1 つの方法を次に示します。

string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }

Console.WriteLine(s)

これは、文字列が null かどうかを確認するのに適している可能性があります。つまり、null は、文字列を初期化するための正当な値である可能性があります。

isInitialized個人的には旗よりこちらの方が好きです。必要がない限り、なぜ追加のフラグ変数を導入するのですか? 私はそれがより読みやすいとは思わない。

于 2012-09-13T20:11:55.123 に答える
2

文字列が初期化されたことを示す別のフラグを保持できます。

string s = null;
bool init = false;
if (conditionOne) {
    s = someValueOne;
    init = true;
}
if (conditionTwo) {
    s = someValueTwo;
    init = true;
}
if (!init) {
    ...
}

これにより、sが割り当てられたときの状況が処理されます。これには、割り当てられたnull、空の文字列、または"zanzibar".

別の解決策は、「初期化されていない」値を示す静的文字列を作成し、変更されたかどうかを確認するObject.ReferenceEquals代わりに使用することです。==ただし、bool可変アプローチでは、意図がより明確に表現されます。

于 2012-09-13T20:05:49.903 に答える
1

可能な場合は null のデフォルト値を使用する必要があるという Vytalyi に同意しますが、すべての型 (int など) が null 可能であるとは限りません。David W で説明されているように、変数を null 許容型として割り当てることもできますが、アクセスする前に null 許容型をプリミティブ型に調整する必要があるため、大規模なコードベースで多くのコードが壊れる可能性があります。

このジェネリック メソッド拡張は、主要な設計上の決定が前任者によって既に行われている大規模なコードベースを扱う場合に役立ちます。

public static bool IsDefault<T>(this T value) 
        => ((object) value == (object) default(T));

ゼロから始めている場合は、null 許容型を利用して null として初期化してください。その C# 機能が実装されたのには理由があります。

于 2021-03-24T15:44:45.520 に答える
0

決して使用できない初期化値を選択します。典型的な値にはString.Empty、、、、nullおよび-1256 文字のランダム文字列ジェネレーターが含まれます。

于 2012-09-13T20:06:43.630 に答える
-2

null一般に、デフォルトをまたはに割り当てますString.Empty。これらの「空の」値を使用できない状況では、アプリケーション固有の初期化されていない値を表す定数を定義します。

const string UninitializedString = "zanzibar";

次に、初期化または初期化のテストを行うときはいつでもその値を参照します。

string foo = UnininitializedString;
if (foo == UninitiaizedString) {
  // Do something
}

文字列は C# では不変の定数であるため、実際にはインスタンスが 1 つしかないことに注意してくださいUninitializedString(これが比較が機能する理由です)。

于 2012-09-13T21:04:31.913 に答える