Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable initialization issue in switch statement

What I have is simple switch statement

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

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

In this situation compiler tells me that

local variable myControl might not be initialized before accessing

So, what is the best way to avoid this situation?

One option is to initialize myControl before switch statement. But in this case I do one more unnecessary initalization.

CASE 1:

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

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

Next option is to change second case with default. After that compiler will "understand" that myControl will be anyway initialized and will not throw exception.

CASE 2:

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

     default:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

But this case doesn't look so good, because after adding some new properties to my enum it will do default for all other types(developer can easily forget to change code here or it can be not necessary to initialize myControl for other enum types).

What is best approach in such situations?

like image 290
Chuck Norris Avatar asked Dec 20 '12 15:12

Chuck Norris


3 Answers

Your code sample indicates that you will always make use of the myControl variable after the switch block. If that's the case, then you should either pre-initialize the variable, or add a default clause (as you mentioned).

If you are concerned that a new enumerated value might be introduced, then you could throw a meaningful exception in the default clause. That would safeguard you from getting a more ambiguous NullReferenceException when you try to dereference the variable later.

like image 127
Matt Dillard Avatar answered Nov 02 '22 12:11

Matt Dillard


Third option: Validate an instance was created before proceeding (instead of relying on it being assigned):

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

You could also add default: fall-through case to the default(TabType) value:

switch (x){
  case TabType.Two:
    // ...
  case TabType.Three:
    // ...
  case TabType.One:
  default:
    // ..
}
like image 26
Brad Christie Avatar answered Nov 02 '22 13:11

Brad Christie


I think that default exists specifically for these situations.

adding some new properties to my enum it will do default for all other types

It will allow your code to work on default premise (Throw an exception or set to a well know value) and thus your code work also for situations not planned before.

Of course, when you implement new properties and expect a different behavior of your code, omitting to update this switch will be an easy bug to spot.

like image 2
Steve Avatar answered Nov 02 '22 13:11

Steve