2

周りを検索した後、C#コンパイラがローカル変数dteDestが行に割り当てられていないことを訴えている理由を見つけることができないようです

if (dteSrc == dteDest) {

行を置き換えるとエラーはなくなります

DateTime dteSrc, dteDest;

DateTime dteSrc, dteDest = DateTime.MinValue;

私が見る限り、dteDestがoutパラメーターであるDateTime.TryParseによって初期化されていない場合、コードは比較行に到達しません。

私の論理は次のとおりです。

  1. currentDataObjがnullの場合、booHaveOrigDateはfalseであり、失敗した場合は最初の
  2. currentDataObjがnullではないが、DateTimeに変換できない場合、booHaveOrigDateはfalseであり、失敗した場合は最初の
  3. DateTime.TryParseは、これを&&とともにDateTimeに変換できない場合、falseを返します。これは、dteDestが使用されないことを意味します。

簡単なサンプルコード

void StrangeLogic(object srcData, object currentDataObj) {
   DateTime dteSrc, dteDest;

   bool booHaveNewDate = DateTime.TryParse(srcData.ToString(), out dteSrc);
   bool booHaveOrigDate = (currentDataObj != null) 
                          && DateTime.TryParse(currentDataObj.ToString(), out dteDest);

   if (booHaveNewDate && booHaveOrigDate) {
      if (dteSrc == dteDest) { 
          // Get a "use of unassignned local variable 'dteDest' 
          // unless dteDest = DateTime.MinValue beforehand
      }
   }
}

また、行を変更した場合

bool booHaveNewDate = DateTime.TryParse(srcData.ToString(), out dteSrc);

次へ

bool booHaveNewDate = (srcData != null) && DateTime.TryParse(srcData.ToString(), out dteSrc);

次に、コンパイラはsrcDateも割り当てられていないと文句を言います。

誰かが私が欠けているものを正しい方向に向けることができますか?私はパラメータチェックなどについては意味しません私はコンパイラロジックが一般的なTryParse関数の使用によってだまされているように見える理由を心配していますか?

追加情報

ロジックを拡張しても同じエラーが発生します(割り当てられていないローカル変数の使用)

bool booHaveOrigDate;
if (currentDataObj != null) 
   booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest); 
else 
   booHaveOrigDate = false;

if (booHaveOrigDate) {
    if (dteSrc == dteDest) {

コンパイラがnullチェック(currentDataObj!= null)を使用して行うことは、割り当てられていない限りdteDestがアクセスされないと正しく判断できないように見えます。

これをこのコードに変更し、問題はありません(nullオブジェクトで発生する可能性のある.ToString()を除く)

bool booHaveOrigDate = DateTime.TryParse(currentDataObj.ToString(), out dteDest); 
if (booHaveOrigDate) {
    if (dteSrc == dteDest) {
4

5 に答える 5

6

置換が正しくありません。次のようになります。

DateTime dteSrc = DateTime.MinValue, dteDest = DateTime.MinValue;

ただし、tryParseの戻り変数を使用する必要があります。これは、booHaveNewDateの場合に代わりにtryparseが機能するかどうかを確認するためのブール値です。

DateTime dteSrc, dteDest;

if(DateTime.TryParse(srcData.ToString(), out dteSrc) && DateTime.TryParse(currentDataObj.ToString(), out dteDest))
{
  if (dteSrc == dteDest) { 
      // Do your stuff here
  }
}

これで、最初に日付を割り当てる必要がなくなります。

**使用する前にこのコードをテストする必要があります。これは製品コードではなく、エラーが含まれている可能性があります

于 2011-10-26T09:05:23.097 に答える
3

コンパイラーは形式的に正しく、dteDestoutパラメーターとしての)への割り当ては条件付きです。コンパイラーの目には、それは起こらないかもしれません。コンパイラは、TryParse()に続くロジックを「理解」しません。

同様の状況があります:

int f(int x)
{
   int r;

   if (x <= 5)  r = 1;
   if (x >  5)  r = 2;

   return r;  // error: use of uninitialized var
}

ちなみに、で初期化する方が少し論理的です。

  DateTime dteSrc = default(DateTime), dteDest = default(DateTime);

ただし、同じ値(DateTime.MinValue)です。

于 2011-10-26T09:11:21.807 に答える
1

私は間違っている可能性がありますが、このエラーを報告するときにコンパイラがコードを広範囲に分析しようとはしないと思います。私は現在、私の理論を裏付けるいくつかの情報源を見つけようとしています。それまでの間、これは設計上の決定だと思います。変数が初期化される前に使用されないことを確認するのに2秒以上かかる場合は、変数をnullで初期化する方がコーディングの決定としておそらく適切です。混乱を避けるために始めます。

編集:

さて、私は少し周りを見回しました、そして私が本質的に同じことを言っている人々のいくつかの例を見つけましたが、私はこれを述べている公式の文書を見つけることができません。私が見つけた応答は次のとおりです。

「コンパイラはあなたの論理を知らないという完全な権利を持っています。」

http://www.pcreview.co.uk/forums/use-unassigned-local-variable-error-t3067479.html

「...制御フロー構造がある場合、コードを実行していないため、状況を評価できません。そのため、値が割り当てられているかどうかがわかりません。」

http://bytes.com/topic/c-sharp/answers/917965-why-am-i-getting-unassigned-local-variable-errors

于 2011-10-26T09:06:28.173 に答える
0

コンパイラロジックは、一般的なTryParse関数の使用にだまされているようです

上記の質問は、コンパイラがコードをコンパイルしているときに、そのメソッドが内部で何を行っているかを調べず、署名だけを調べるという事実によって最も簡単に答えることができます。trueまたはfalseのブール値を返すことができ、の値を設定していることを認識していますdteDest

しかし、これは実際にはあなたの問題ではありません。問題は次の行にあります。

bool booHaveOrigDate = (currentDataObj != null) 
          && DateTime.TryParse(currentDataObj.ToString(), out dteDest);

&&最初の部分がfalseの場合、2番目の部分を評価しない演算子を使用します。これは短絡評価と呼ばれ、最初の部分が偽の場合、2番目の部分が何であるかは問題ではないという理論に基づいて機能します。全体的な結果は常に偽になります。

したがって、この場合、dteDestは設定されておらず、コンパイラーは、ロジックを見て、設定されていないとコードが実行されないと言っても、これが問題であると感じます。

単純な事実は、多くの場合、コンパイラを超えた最適化や特殊なケースを見つけることができるということです。最初にパラメータをチェックし、nullの場合は返すだけで、これを解決できることをすでに知っているように聞こえます。

于 2011-10-26T09:20:18.427 に答える
0

dteDest次の場合、値は設定されませんcurrentDataObj == null

次のように行を変更すると機能します。

bool booHaveOrigDate = DateTime.TryParse(currentDataObj != null ? currentDataObj.ToString() : string.Empty, out dteDest);
于 2011-10-26T09:07:01.780 に答える