Reputation: 15200
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?
Upvotes: 6
Views: 2328
Reputation: 62002
I do one more unnecessary initalization
I also don't like that.
Like manye people have already said, add an extra default:
section to your switch
statement. Like this:
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);
This is because from your question we understand that you know that x
will always have one of those two values. The compiler doesn't know that. The above code will tell it so.
Upvotes: 1
Reputation: 216333
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.
Upvotes: 2
Reputation: 14863
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.
Upvotes: 6
Reputation: 203821
You have to do one of the two options; either specify the initial value before the switch
, or add a default
case so that the compiler knows for sure that the switch
will initialize the variable.
I would suggest that if the switch doesn't initialize the variable it's possible that you just want to throw an exception. In that case, just add that code to the default
case. That way it's clear in testing when a developer forgets to add the case
for a new enum value, as opposed to just silently not working.
Upvotes: 0
Reputation: 101614
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:
// ..
}
Upvotes: 3