web-dev-qa-db-ja.com

C#エラー:未割り当てのローカル変数の使用

なぜこのエラーが発生するのか分かりませんが、キューが初期化されているかどうかをすでに確認しているので、このコードをコンパイルするべきではありませんか?

public static void Main(String[] args)
{
    Byte maxSize;
    Queue queue;

    if(args.Length != 0)
    {
        if(Byte.TryParse(args[0], out maxSize))
            queue = new Queue(){MaxSize = maxSize};
        else
            Environment.Exit(0);
    }
    else
    {
        Environment.Exit(0);
    }

    for(Byte j = 0; j < queue.MaxSize; j++)
        queue.Insert(j);
    for(Byte j = 0; j < queue.MaxSize; j++)
        Console.WriteLine(queue.Remove());
}

キューが初期化されていない場合、forループに到達できませんか?プログラムはすでにEnvironment.Exit(0)で終了しているのですか?

Yaが私にいくつかのポインタを与えることができることを願っています:)

ありがとう。

28
jkidv

コンパイラーは、Environment.Exit()がプログラムを終了することを知りません。クラスで静的メソッドを実行しているだけです。 queueを宣言するときにnullに初期化するだけです。

Queue queue = null;
75
tvanfosson

コンパイラーは、Environment.Exit()が戻らないことを知りません。なぜMain()から「戻る」だけではありませんか?

9
Brian

問題を解決するためのいくつかの異なる方法:

Environment.Exitをreturnに置き換えるだけです。コンパイラは、returnがメソッドを終了することを知っていますが、Environment.Exitが終了することを知りません。

static void Main(string[] args) {
    if(args.Length != 0) {
       if(Byte.TryParse(args[0], out maxSize))
         queue = new Queue(){MaxSize = maxSize};
       else
         return;
    } else {
       return;   
}

もちろん、すべての場合で終了コードとして0を使用しているため、実際にはそれだけで逃げることができます。本当に、Environment.Exitを使用する代わりにintを返す必要があります。この特定のケースでは、これは私の好みの方法です

static int Main(string[] args) {
    if(args.Length != 0) {
       if(Byte.TryParse(args[0], out maxSize))
         queue = new Queue(){MaxSize = maxSize};
       else
         return 1;
    } else {
       return 2;
    }
}

キューをnullに初期化します。これは、実際には「初期化されていない変数を見つけます。ありがとうございます」というコンパイラーのトリックです。これは便利なトリックですが、この場合は好きではありません。ブランチが多すぎると、正しく実行されていることを簡単に確認できません。 実際にをこの方法で実行したい場合、次のようなことがより明確になります。

static void Main(string[] args) {
  Byte maxSize;
  Queue queue = null;

  if(args.Length == 0 || !Byte.TryParse(args[0], out maxSize)) {
     Environment.Exit(0);
  }
  queue = new Queue(){MaxSize = maxSize};

  for(Byte j = 0; j < queue.MaxSize; j++)
    queue.Insert(j);
  for(Byte j = 0; j < queue.MaxSize; j++)
    Console.WriteLine(queue.Remove());
}

Environment.Exitの後にreturnステートメントを追加します。繰り返しますが、これはコンパイラーのトリックに近いものですが、人間にもセマンティクスを追加するため、わずかに正当なIMOです(ただし、その100%のコードカバレッジからは外れます)

static void Main(String[] args) {
  if(args.Length != 0) {
     if(Byte.TryParse(args[0], out maxSize)) {
        queue = new Queue(){MaxSize = maxSize};
     } else {
        Environment.Exit(0);
        return;
     }
  } else { 
     Environment.Exit(0);
     return;
  }

  for(Byte j = 0; j < queue.MaxSize; j++)
     queue.Insert(j);
  for(Byte j = 0; j < queue.MaxSize; j++)
     Console.WriteLine(queue.Remove());
}
8
Mark Brackett

コンパイラは、「return」を使用した場合にコードが到達可能であるか到達できないことのみを認識します。 Environment.Exit()を呼び出す関数と考えてください。コンパイラは、アプリケーションが終了することを知りません。

0
Nelson Reis