I have been writing a Winforms application, in which the user selects something from a comboBox. However, when I run the application, the compiler throws an ArgumentOutOfRange Exception because the index was -1.
Code:
if (comboBox1.Enabled == false || comboBox2.Enabled == true || comboBox3.Enabled == false)
{
int index = comboBox2.SelectedIndex;
string t = comboBox2.Items[index].ToString();//<==EXCEPTION
switch (t)
{
case "Ounzes==>Pounds":
break;
case "Pounds==>Ounzes":
break;
case "Tons==>Pounds":
break;
case "Pounds==>Tons":
break;
case "Ounzes==>Tons":
break;
case "Tons==>Ounzes":
break;
case "Stone==>Pound":
break;
case "Pound==>Stone":
break;
case "Tons==>Stone":
break;
case "Stone==>Ton":
break;
}
}
Can anyone please explain why this exception is being thrown, because I did select something from the comboBox.
It appears that no item was selected in your ComboBox. Take a look at the documentation:
A zero-based index of the currently selected item. A value of negative one (-1) is returned if no item is selected.
The most obvious way to fix this is just to check to make sure an item has been selected before you try to use it, like this:
int index = comboBox2.SelectedIndex;
if (index >= 0)
{
string t = comboBox2.Items[index].ToString();
switch (t)
{
...
}
}
Check when your code is firing. Might be when combo1 is being populated, but combo2 hasn't yet.
As others have said quick way is to test selectedIndex >= 0 or selectItem != null.
The best thing to do would be,put the code in a try catch block and you'll find out answers for yourself :)
Related
I have a method which has result at the end,I would want to detect if number is not 0 and if it's -4.
0 Means good
-4 Means something that can be solve
And anything else is bad.
Like
if ( Result != 0)
{
MessageBox.Show("It's bad!")
}
else if ( Result == -4)
{
Thread.Sleep(20000);
MyMethod.TryAgain();
}
else
{
MessageBox.Show("It's good");
}
My problem is that -4 is not 0,so if i get result -4 it takes my Result != 0 method. How can I solve it? Thank you in advance.
Use switch and case.
switch (Result) {
case 0:
MessageBox.Show("It's good");
break;
case -4:
Thread.Sleep(20000);
MyMethod.TryAgain();
break;
default:
MessageBox.Show("It's bad!");
break;
}
Microsoft documentation: https://msdn.microsoft.com/en-us/library/06tc147t(v=vs.110).aspx
Just reorder your if-structure to the following:
if ( Result == 0)
{
MessageBox.Show("It's good")
}
else if ( Result == -4)
{
Thread.Sleep(20000);
MyMethod.TryAgain();
}
else
{
MessageBox.Show("It's bad");
}
So your initial problem, that the Result != 0 case is evaluated first, is gone.
Simply change order of branches
if (Result == -4) \\ solve
else if (Result != 0) \\ bad
else \\ good
When you are building a chain of non-exclusive conditions, start with the strongest one (i.e. the most specific condition). Otherwise the code for the weaker condition will execute, blocking access to more specific ones.
In your case, Result == -4 implies that Result != 0, meaning that the first condition is more specific than the second one. Hence you should check Result == -4 before Result != 0. Otherwise, Result == -4 would never be reached.
C# offers multiple ways of implementing this logic. As long as you follow a general rule of ordering your conditionals from most specific to least specific, picking a particular implementation is up to you.
Sorry, wrong code. See comment below.
switch(Result) {
case 0:
MessageBox.Show("It's bad!");
break;
case -4:
Thread.Sleep(20000);
MyMethod.TryAgain();
break;
default:
MessageBox.Show("It's good");
break;
}
I have a try {} catch {} for each line my user inputs something, this is to ensure it's in the right format/range/acceptable. However it doesn't seem to... well work! Here is one of my examples.
string userAnswer;
bool errorHandling = true;
while (errorHandling){
try{
userAnswer = Console.ReadLine();
if (userAnswer == "1") {
singleGrade.grapher(acount, bcount, ccount, dcount, ecount, fcount);
}else{
if (userAnswer == "2"){
readIn.Classes(SingleGrade[1]);
}else{
if (userAnswer == "3"){
countAll.allGrades(multiGrade);
} else{
errorHandling = false;
}
}
}
}
catch (FormatException a){
Console.WriteLine(a.Message);
//Console.WriteLine("Error - please enter a number between 1 & 6.");
}
} // end of While loop
If someone could please explain to me why no error is caught when an invalid number is placed/not in the correct format.
There is no FormatException being thrown because valid strings are being entered. If you were to convert the user input to an integer, for example, that would throw a FormatException. But since you are leaving it as a string, no exception is being thrown.
However, since you are really only trying to restrict user input, and nothing truly exceptional is happening here, you should probably just handle it through you application logic.
What you are really looking for is probably something like this:
bool errorHandling = true;
while (errorHandling)
{
string userAnswer = Console.ReadLine();
switch (userAnswer)
{
case "1":
singleGrade.grapher(acount, bcount, ccount, dcount, ecount, fcount);
errorHandling = false;
break;
case "2":
readIn.Classes(SingleGrade[1]);
errorHandling = false;
break;
case "3":
countAll.allGrades(multiGrade);
errorHandling = false;
break;
// cases for 4, 5, and 6...
default:
Console.WriteLine("Error - please enter a number between 1 & 6.");
break;
}
} // end of While loop
You're not throwing and exception when the number is invalid, you're just handling a bunch of if statements - thus, since there is no throw statement, nothing can hit the catch statement, and insteadyou're seeing what we colloquially call a "Fall through error" - logic is proceeding past where it should.
If you want an exception when input is invalid, just add a throw new FormatException to the end of the if statements, so you get a "if we make it here there's a problem" behaviour.
The reason is that you are grabbing a string, and not trying to convert it to anything else, so there is no FormatException.
I would get away from using the try / catch for input validation, and instead use the TryParse method of the Int type.
What I usually do is write a separate function to get validated input from the user, then call that from my main code. In this case, since you have upper and lower bound requirements, you might consider writing something like this:
public static int GetBoundedIntFromUser(int minVal, int maxVal)
{
if (minVal >= maxVal)
{
throw new ArgumentException("minVal must be less than maxVal.");
}
int input;
while (true)
{
Console.Write("Please enter a number from {0} to {1}: ", minVal, maxVal);
if (int.TryParse(Console.ReadLine(), out input)
&& input >= minVal && input <= maxVal)
{
break;
}
Console.WriteLine("That input is not valid. Please try again.");
}
return input;
}
Then you can just call it from your main code (without any try catch), like:
switch (GetBoundedIntFromUser(1, 3))
{
case 1:
singleGrade.grapher(acount, bcount, ccount, dcount, ecount, fcount);
break;
case 2:
readIn.Classes(SingleGrade[1]);
break;
case 3:
countAll.allGrades(multiGrade);
break;
default:
break;
}
if (((turn % 2) != 0) && (vsComputer))
{
int generateAI = generateRandomAI(AI);
switch (generateAI)
{
case 0:
computerMedio();
break;
case 1:
computerDifficile();
break;
}
}
I want my 0/1 value to be the same for all the game.
With the code I wrote, on every move it selects a different AI mode.
It shouldn't be that hard to achieve, but I can't find a solution.
Thanks everyone!
Your issue is:
int generateAI = generateRandomAI(AI);
You are generating a new random value on every invocation of this code block. If you wish to keep the same value for all execution, just generate the value once and keep it in scope.
Ok I solved in the following way
public Boolean difficult;
in the newGame() method I generate the number which lasts for all the game.
then,
switch (generateAI)
{
case 0:
difficult = false;
break;
case 1:
difficult = true;
break;
}
into the game:
if (((turn % 2) != 0) && (vsComputer))
{
if (difficult)
{
computerDifficile();
}
else
{
computerMedio();
}
}
When I try to evaluate the SelectedIndex of a CheckBoxList and at bool. I receive a error on the case in my switch statement in C#. The error is Constant value '0' cannot be converted to a 'bool'. Is there a way that I can evaluate both with in a switch statement? I know I can use a if statement, but I would rather use a switch statement if I could.
Here is my code:
switch ((CBL_PO.SelectedIndex == 0) && (boolIsNotValid == true))
{
case 0: case true:
//Do Something
break;
}
Since the only values in the switch can be true or false, drop the case 0.
Alternatively, you could better use an if:
if (CBL_PO.SelectedIndex == 0 && boolIsNotValid)
{ }
else
{ }
Since I think you might be trying to do a check on both values in the switch: not possible. This is your best option:
switch (CBL_PO.SelectedIndex)
{
case 0:
{
if (boolIsNotValid)
{ }
else
{ }
break;
}
}
A switch statement can be thought of as a replacement for a stack of if/else statements. If you are doing a single comparison then use a simple if statement; switch is overkill.
if (CBL_PO.SelectedIndex == 0 && boolIsNotValid)
{
// Do something
}
If you really want to use a switch statement, then you want:
switch ((CBL_PO.SelectedIndex == 0) && (boolIsNotValid == true))
{
case true:
//Do Something
break;
case false:
//Do Something else
break;
}
I'm getting the error "A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type" in my code at the line,
switch (job_selecter.SelectedValue)
Here's my code:
private void start()
{
switch (job_selecter.SelectedValue)
{
case 0:
head_seal_label.Text = "Ravager's Seal: Head (8)";
break;
}
}
Could anyone tell me why this is happening and how I can fix it? Thanks!
job_selecter.SelectedValue is probably an object.
private void start()
{
int index = (int)job_selecter.SelectedValue;
switch (index )
{
case 0:
head_seal_label.Text = "Ravager's Seal: Head (8)";
break;
}
}
It seems like what you really want to do is this:
switch(job_selecter.SelectedIndex)
{
case 0:
// do whatever
break;
default:
// handle default case
break;
}
You've noted in one of your responses that casting SelectedValue to string or int or whatever can cause a null reference exception if you then use it in a switch--which makes perfect sense, because it's perfectly legal for a combo box to have nothing selected, and you're going to need to account for that case. If you switch on SelectedIndex, handling -1 will allow you to handle a case of "no selection" specifically.
Of course, it's worth pointing out that switching on SelectedIndex only makes sense if the combo box contains a known, unchanging set of values. Adding or removing values will potentially cause the indices of everything in the box to change, thus breaking the switch.
SelectedValue is an object. cast it to an int in the switch.
You might have meant to use "SelectedIndex" property (a zero based number corresponding to your selection in combo OR a -1 when nothing is selected):
switch (job_selecter.SelectedIndex)
{
case 0:
head_seal_label.Text = "Ravager's Seal: Head (8)";
break;
// other cases for other Indices
case -1:
default:
// handle nothing selected...
}
You should get your SelectedIndex into an int first, to deal with this error " "A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type" in my code at the line":
int index;
if(!Int32.TryParse(job_selector.SelectedIndex.ToString(), out index))
{
index = -1;
}
//All your other cases here
switch(index)
{
case 0:
head_seal_label.Text = "Ravager's Seal: Head (8)";
break;
default:
head_seal_label.Text = "Some default Value";
break;
}