2012-09-13 11 views
11

プログラムで実行時に変数が初期化されているかどうかを確認したい。この理由を不思議にするには、以下の不完全なコードを参照してください。C# - 変数が初期化されているかどうかの確認

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."); 

そして、関連するビットを完成させてください。それが変更された場合はチェックし

string s = "zanzibar"; 

そして:

一つのハックソリューションは、デフォルト値でSを初期化することであるsomeValuesomeOtherValueは「ザンジバル」ことが起こるならば何が

bool sIsUninitialized = s == "zanzibar"; 

、同じように?それから私にはバグがあります。もっと良い方法?

+5

'string.IsNullOrEmpty(s)' – Shmiddty

+7

これは実際にはコンパイルされません。変数を初期化する必要があります。 nullまたはstring.Emptyに初期化するだけです。 – McGarnagle

+0

変数が別のスレッドによって初期化されるとどうなりますか?あなたは書き込みアクセスの例外を生成するためにメモリコントローラを設定するのに慣れていますか? – HABO

答えて

12

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

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 
    } 
} 

documentation状態デフォルト(T)は、基準タイプのnullを与えること、及び値タイプの0。コメントで指摘されているように、これは実際にnullをチェックするのと同じです。


このすべては、あなたが本当に彼らが最初に宣言されているnullまたは任意に、変数を初期化すべきであるという事実をあいまいにしています。

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

これはsが割り当てられているとき、それは、null空の文字列を割り当てられたときのケースを含め、状況の世話をする、もしくはます:

+4

's == default(string)'は 's == null'と言ってもいいのですか? – dasblinkenlight

+1

@dasblinkenlightうん、はい、基本的には、私はそれが意図をもう少し明示的にすると思う。 – McGarnagle

+10

@dbaseman、私は同意しません。 '' null''が何のためのものなのか、よく知られている理解を難読化しています。 –

2

あなたは文字列が初期化されていることを示し、別のフラグを維持することができます"zanzibar"

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

+0

フラグを導入して 's'と' null'を比較するのはなぜですか? –

+5

@KirkWollそれは素晴らしい質問ですが、私は答えて答えてみました: 'someValueOne'または' someValueTwo'は正当に 'null'になる可能性があるからです。 (更新:明らかに、OPは気にしない:) – dasblinkenlight

+0

十分に公正で、私は十分にあなたの答えを読んでいない。 ;) –

0

使用できない初期値を選択します。通常、値はString.Emptynull-1、および256文字のランダムストリングジェネレータが含まれます。

+2

'string.Empty' =' "" ' 3倍以上の冗長な方法を使用する必要はありません。結局、私たちは 'Int32.Zero'のようなものを使用しません。 –

+0

私はString.Emptyを '' ''と混同しない方が好きです。それは私のために読むのが簡単です。 –

+2

あなたは '" "によって混同しないでください。本当に。これはプログラミング言語の不可欠な部分です。 –

3

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

+0

もし 'null'がその文字列の' if'文の一つに代入される有効な値であれば? – Servy

+0

@Servy次に、nullでない、初期化されていない値を表す定数を定義します。 'const string UninitializedString =" zanzibar ";' –

+1

@PeterGluckその定数値が「無効」になり、悪化すると、デバッグが非常に困難になります。あらゆる種類の頭痛を引き起こすであろう。 – Servy

8

C#2.0では、あなたがそのようなもののためにできるように、あなたがこれまでの値の型にnullの初期値を設定することを可能にするのNullableオペレータがあります

int? x = null; 

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

この結果は、 "xの値:Null"となります。多分someValueのは時々nullを返すことができる方法であるため、これは文字列がnullであるかどうかをチェックするのに好適であるかもしれない

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

Console.WriteLine(s) 

+2

参照型であるため、これは文字列には適用されません。 – dasblinkenlight

+0

OPの入門文では、「実行時に変数が初期化されているかどうかをチェックしたい」と述べています。このタイプは、OPに記載されている "incomplete code"の例の文字列でしかありませんでした。 –

+2

チェックでブールリテラルを使用しないで、 'if(x.HasValue)'と書いてください。ブールリテラルは、初期化(またはパラメーターとして渡された場合)でのみ意味があります。 –

3

は、ここに1つの方法です。言い換えれば、おそらくヌルは文字列を初期化する正当な値です。

個人的に私はこれをisInitializedフラグよりも好きです。あなたがしなければ特別なフラグ変数を導入するのはなぜですか?私はそれがより読みやすいとは思わない。

+0

明らかに 'someValue'はメソッドではなく、' SomeValue() 'になりますが、実際の(単純化されていない)場合を意味します。それはどんなレートでも「ヌル」になる可能性があります。 –

-1

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

const string UninitializedString = "zanzibar"; 

は、その値を参照:

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

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

+1

これは災害のためのレシピです。ある時点で、「初期化されていない」値に対する合法的な割り当てに終わる可能性があり、それがなぜ機能していないのかを判断しようとするプログラマーにあらゆる種類の混乱を引き起こします。 – Servy

+0

@Servyそうではありません。つまり、コード全体に「裸の」文字列を振りかけるのではなく、名前付き定数を使用するのはまさにその理由です。定数は必要に応じて変更することができます。最初の選択は 'null'か' String.Empty'を使うことです。実際、 'const string UninitializedString = String.Empty;'が私の最初の選択です。 –

+1

最初にコード全体に「裸の」文字列を振りかけることはありません。 [this one](http://stackoverflow.com/a/12414058/1159478)のような、「初期化されていない値」を表現するための値を決して使用しないソリューションを使用します。コンパイル時にそれを変更できるとすれば、ここでの危険性を大幅に軽減することさえありません。文字列がユーザの入力に基づいている場合は、コンパイル時にユーザが何を選択するか分かりません。あなたが選んだものが間違っているかもしれません。実際には 'null'や空の文字列への有効な代入をするのは珍しいことではないので、それを使うことは役に立たないでしょう。 – Servy

関連する問題