3

私はこのコードを持っています...

var i = int.MinValue;
var s = string.Empty;
int.TryParse(s, out i);

TryParseステートメントの後、i変数の値が上書きされ ( as zero)、以前の値が失われます。

これはバグですか?outいいえの場合、パラメーターとして渡された変数を再初期化する必要があった理由について、実装の詳細はありますか?

4

5 に答える 5

8

全体的なポイントは、この値を上書きoutすることを保証することです(少なくとも C# レベルでは... IL レベルではありません)。これの目的は、「明確な割り当て」を許可しながら、不要な割り当てを回避することです。例えば:

int i; // note: not assigned
var s = string.Empty;

// here "i" is not "definitely assigned"
int.TryParse(s, out i);
// here "i" is "definitely assigned"

アイデアは、戻り値を使用することです。たとえば、次のようになります。

if(int.TryParse(s, out i)) {
   // here "i" makes sense; feel free to use it
} else {
   // here you shouldn't use the value of "i"
}

特定のケースでは、次の順序で並べ替えることができます。

if(!int.TryParse(s, out i)) i = int.MinValue;

特に、(少なくとも C# では) メソッドは値を割り当てる必要があり、入力値を使用できないことに注意してください。例えば:

static void Foo(out int i) {
    return; // error: hasn't assigned to i
}
static void Bar(out int i) {
    int j = i; // error: cannot read from "i" until Bar has assigned a value
    i = j;
}
static void Baz(out int i) {
    i = 0; // note that after this assignment, code in Baz can read from "i"
}

とは対照的refです。ref値を渡すときは、呼び出し側で確実に割り当てる必要があります。メソッド自体は、入力値を参照する場合と参照しない場合があり (選択した場合)、新しい値を割り当てる場合としない場合があります (選択した場合) 例えば:

int i;
SomeMethod(ref i); // illegal - "i" is not definitely assigned

int i = 0;
SomeMethod(ref i); // legal

と:

static void Foo(ref int i) {
    return; // perfectly legal to not look at "i" and/or not assign "i"
}
static void Foo(ref int i) {
    i = i + 1; // perfectly legal to look at "i" and/or assign "i"
}
于 2013-05-22T07:32:26.347 に答える
5

これはバグではありません。変換に失敗するとゼロが返されます。この場合の関数の戻り値は false になります。

このメソッドが戻るときに、変換が成功した場合は s に含まれる数値に相当する 32 ビットの符号付き整数値を含み、変換が失敗した場合は 0 を含みます。s パラメータが null の場合、正しい形式でない場合、または MinValue 未満または MaxValue より大きい数値を表している場合、変換は失敗します。このパラメーターは初期化されずに渡されます。

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

于 2013-05-22T07:27:33.843 に答える
2

アウト (C# リファレンス)

out 引数として渡される変数は、渡す前に初期化する必要はありませんが、呼び出し元のメソッドは、メソッドが を返す前に値を割り当てる必要があります

Int32.Parseゼロで初期化しdefault(int)ます。

sこのメソッドが戻るときに、変換が成功した場合は に含まれる数値に相当する 32 ビットの符号付き整数値を含み、変換が失敗した場合は 0を含みます。

于 2013-05-22T07:32:40.553 に答える
1

out パラメータなのでバグではありません。演習として、out パラメーターの値を設定しない C# を書いてみてください。(ヒント: それは不可能です) したがって、観察される結果は唯一の論理的な結果です。out 変数は「再初期化」されておらず、単に初期化されているだけです。

TryParse が ref int を取るように書かれていれば、あなたが望むことは可能だったでしょう。個人的には、ここでは int の方が優れていると思います。

于 2013-05-22T07:35:59.943 に答える