6

私が持っているのは単純なswitchステートメントです

Control myControl;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

この状況では、コンパイラは私にそれを教えてくれます

ローカル変数 myControl は、アクセスする前に初期化されていない可能性があります

では、この状況を回避する最善の方法は何ですか?

1 つのオプションは、switch ステートメントの前に myControl を初期化することです。しかし、この場合、不要な初期化をもう 1 つ行います。

ケース 1:

Control myControl = null;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

次のオプションは、2 番目のケースを で変更することdefaultです。その後、コンパイラは myControl がとにかく初期化され、例外をスローしないことを「理解」します。

ケース 2:

Control myControl;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     default:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

しかし、このケースはあまり良くありません。列挙型にいくつかの新しいプロパティを追加した後、他のすべての型のデフォルトを実行するためです (開発者はここでコードを変更することを簡単に忘れたり、他の列挙型の myControl を初期化する必要がない可能性があります)。 .

そのような状況での最善のアプローチは何ですか?

4

5 に答える 5

6

コード サンプルはmyControl、switch ブロックの後に常に変数を使用することを示しています。その場合は、変数を事前に初期化するか、default句を追加する必要があります(前述のとおり)。

新しい列挙値が導入される可能性があることを懸念している場合は、default句で意味のある例外をスローできます。NullReferenceExceptionこれにより、後で変数を逆参照しようとしたときに、より曖昧になるのを防ぐことができます。

于 2012-12-20T15:40:03.487 に答える
3

3番目のオプション:(割り当てられていることに依存するのではなく)続行する前にインスタンスが作成されたことを検証します。

Control mycontrol = null;
switch (x){
  // ...
}
if (myControl != null){
  // add to controls list, manipulate, etc.
}

default:フォールスルーケースをdefault(TabType)値に追加することもできます。

switch (x){
  case TabType.Two:
    // ...
  case TabType.Three:
    // ...
  case TabType.One:
  default:
    // ..
}
于 2012-12-20T15:38:20.093 に答える
2

defaultそれは特にこのような状況のため に存在すると思います。

列挙型にいくつかの新しいプロパティを追加すると、他のすべてのタイプでデフォルトになります

これにより、コードがデフォルトの前提で機能するようになり(例外をスローするか、よく知られた値に設定されます)、したがって、コードは以前に計画されていなかった状況でも機能します。

もちろん、新しいプロパティを実装し、コードの動作が異なると予想される場合、このスイッチの更新を省略すると、簡単に発見できるバグになります。

于 2012-12-20T15:39:42.187 に答える
1

不要な初期化をもう 1 つ行う

私もそれが好きではありません。

多くの人がすでに言っているように、ステートメントに余分なdefault:セクションを追加してください。switchこのような:

Control myControl;
switch(x)
{
  case TabType.Edit:
    myControl= ...;
    break;

  case TabType.View:
    myControl= ...;
    break;

  default:
    throw new Exception("Unexpected value of x: " + x);        
 }

 myPageView.Controls.Add(myControl);

これは、あなたの質問から、が常にこれら 2 つの値のいずれかを持つことを知っていることを理解しているからです。xコンパイラはそれを知りません。上記のコードはそう伝えます。

于 2012-12-20T15:48:09.387 に答える
0

2 つのオプションのいずれかを実行する必要があります。の前に初期値を指定するかswitch、ケースを追加して、が変数を初期化するdefaultことをコンパイラが確実に認識できるようにします。switch

スイッチが変数を初期化しない場合は、例外をスローしたいだけである可能性があることをお勧めします。その場合は、そのコードをケースに追加するだけdefaultです。そうすれば、開発者がcase新しい列挙値に追加するのを忘れたときに、黙って動作しないのではなく、テストで明確になります。

于 2012-12-20T15:39:55.410 に答える