Checking number range not working - c#

private bool DataValidation(string Checker)
{
int i;
if (Int32.TryParse(Checker, out i))
{
return true;
}
else
{
return false;
}
}
private void NumberChecker()
{
if (int.Parse(txtRank.Text) >= 0 || int.Parse(txtRank.Text) <= 50)
{
errorProvider1.SetError(txtRank, string.Empty);
errorProvider1.Clear();
}
else
{
errorProvider1.SetError(txtRank, "Between 1 and 50 please!");
}
}
private void txtRank_Validating(object sender, CancelEventArgs e)
{
if (DataValidation(txtRank.Text) == false)
{
errorProvider1.SetError(txtRank, "Must be numeric!");
}
else
{
errorProvider1.SetError(txtRank, string.Empty);
errorProvider1.Clear();
}
NumberChecker();
}
I've been trying to get this to work for about 4 hours, can someone please tell me why it keeps saying "String in the wrong format" I've tried all of this inside the the validation event, nothing I do is working. I am not understanding why.
Update:
private void txtRank_Validating(object sender, CancelEventArgs e)
{
if (DataValidation(txtRank.Text) == false)
{
errorProvider1.SetError(txtRank, "Must be numeric!");
}
else
{
errorProvider1.SetError(txtRank, string.Empty);
errorProvider1.Clear();
}
if (Convert.ToInt32(txtRank.Text) >= 0 && Convert.ToInt32(txtRank.Text) <= 50)
{
errorProvider1.SetError(txtRank, string.Empty);
errorProvider1.Clear();
}
else
{
errorProvider1.SetError(txtRank, "Between 1 and 50 please!");
}
}
if i use the code above, i can either do one or the other, but i have to comment out a section of code in order to do that.

You're doing a lot of stuff here that isn't necessary at all.
First off: Assuming that the if statement in your DataValidation method is only intended to have the return true and return false, the if statement is totally unnecessary. You could just say return Int32.TryParse(Checker, out i); and it would do the exact same thing. In fact, you could remove the int i in the first place, and just do this:
private bool DataValidation(string Checker) {
return Int32.TryParse(Checker, out int i);
}
out int i creates a temporary variable... and since the DataValidation method is now a single method call, you may realize that the whole method is now unnecessary. You could simply replace any call to DataValidation(someString) with Int32.TryParse(someString, out int i) with no side effects.
Moving on to your NumberChecker method, the error becomes immediately apparent:
if (int.Parse(txtRank.Text) >= 0 || int.Parse(txtRank.Text) <= 50)
This is the only place in your code where you are parsing a string without checking to ensure that it's a number first. Evidently, txtRank.Text is a string that is not a proper number. This is actually where TryParse would come in handy.
I'm going to assume that you don't know exactly what TryParse does and that you were only using it as an error checker, which is okay, because the function of out arguments aren't immediately apparent.
The out keyword, effectively, allows a function to change the thing that was passed in. Take the following code snippet:
public static void Main(string[] args)
{
String foo = "abc";
DoSomething(out foo);
Console.WriteLine(foo);
}
private static void DoSomething(out String something)
{
something = "def";
}
Despite DoSomething not returning a value, the Console.WriteLine(foo); will write def rather than abc. Int32.TryParse uses this to its advantage: It returns a bool that says whether the operation was successful or not. And if it was successful, it stores the result in the variable used as the out argument.
As such, your NumberChecker method should look something like this:
private void NumberChecker()
{
int num = null;
if (Int32.TryParse(txtRank.Text, out num) {
// if TryParse returns true, then we have a result in `num`.
if (num >= 0 && num <= 50)
{
errorProvider1.SetError(txtRank, string.Empty);
errorProvider1.Clear();
}
else // txtRank.Text is a number, but is not within the range
{
errorProvider1.SetError(txtRank, "Between 1 and 50 please!");
}
}
else // txtRank.Text is not a number to begin with
{
errorProvider1.SetError(txtRank, "txtRank.Text is not a number!");
}
}
Worth noting: Since NumberChecker() can now handle the case of invalid text like txtRank_Validating() used to, you can now remove txtRank_Validating() as well. NumberChecker() is now the only necessary code.
One final thing worth noting: In your original code, although your txtRank_Validating() has if statements for in case txtRank.Text was not a number, the reason it was still failing was because NumberChecker() was called at the end of the method whether the text was a number or not. In that sense, the easiest solution would have just been to move the NumberChecker(); call to after errorProvider1.Clear(); inside the else block. But I think the rest of the details in this answer are worth taking note of.

Related

How to terminate a method execution Midway in C#?

I need to exit from a method when a certain condition is reached. The other lines of code should not be executes after exit Condition is reached. what is the best way for this I have tried to use Environment.Exit(0), but it causes problem in my logic.
Exit(0) does not seem to work unless in a loop
We have two possibilities: normal (return) and abnormal (throw) termination:
public static int Factorial(int value) {
// We can't compute factorial for negative and too large values
if (value < 0 || value > 12)
throw new ArgumentOutOfRangeException(nameof(value)); // Abnormal termination
if (value == 0)
return 1; // Normal termination: special case in which we know the answer
...
}
The "return" statement exits condition-blocks aswell as loops and methods.
public void myMethod(int a){
if( 1 == a) {
return;
}
// do something with a
}
As some people have already said before me, return is the way to go.
Here is an example where an if statement compares two integers and returns if they are equal:
public void isEqual(int a, int b) {
if (a == b) {
Console.WriteLine("Integers are equal");
return; //Return to executing the rest of the program.
}
else {
Console.WriteLine("Integers are not equal");
}
}

How can I handle an exception in C#? [duplicate]

This question already has answers here:
Parse v. TryParse
(8 answers)
Closed 5 years ago.
I'm trying to handle an exception to avoid my program crash if double.Parse(string) tries parsing invalid values (such as strings instead of numbers). Here's what I've got:
do
{
//asking customer the amount of shirts he would like to buy any shirts they want.
numbershirtString = Console.ReadLine(); // customer types in amount of shirts they want.
numbershirts = double.Parse(numbershirtString);
keepLooping = true;
if (numbershirts < 10)
{
Console.WriteLine("You would be buying " + numbershirts + " shirts");
keepLooping = false;
}
if (numbershirts > 10)
{
Console.WriteLine("You cannot order more than 10 shirts. Please try again.");
keepLooping = true;
}
} while (keepLooping);
I would appreciate your help. Thank you in advance!
Use double.TryParse() instead. It returns true of false depending on the outcome:
double val;
bool success = double.TryParse("red", out val);
if(success)
{
// val contains a parsed value
}
else
{
// could not parse
}
To handle an exception, in C# like similar in other languages, you can use the try..catch block.
Look at the simplest syntax:
try
{
//Try to run some code.
}
catch
{
//Do something if anything excepted.
}
If you're interested to retrieve which exception breaked the code:
try
{
//Try to run some code.
}
catch (Exception ex)
{
//Do something ex was thrown.
}
If you change the type of ex to something inheriting the base class Exception you'll handle only all the exception of that type:
try
{
//Try to run some code.
}
catch (StackOverflowException ex)
{
//Do something ex was thrown because you overflowed the stack.
}
But instead of talking about try..catch block which you can find out more about on Google, I suggest you to use the method double.TryParse(string, out double).
Its syntax is a little bit different than double.Parse, but effectively it does the same in a different way.
It returns true if your input is valid, else it returns false, whereas in the first parameter you have just to pass your string input and in the second one is required an output reference to the result variable:
double x = 0;
string number = "125.3";
if (double.TryParse(number, out x))
Console.WriteLine("Your number is " + x.ToString());
else
Console.WriteLine("Your input isn't valid");
Maybe this is a little advanced for you, but if you are feeling in a clever mood, you can define a class that handles the parsing of user input. That way you can keep that logic separated from your main program (see separation of concerns).
public class UserEntry
{
private readonly string _originalValue;
public UserEntry(string input)
{
_originalValue = input;
}
public bool IsInt
{
get
{
return int.TryParse(_originalValue, out var dummy);
}
}
public int ToInt()
{
return ToInt(default(int));
}
public int ToInt(int defaultValue)
{
int result;
bool ok = int.TryParse(_originalValue, out result);
return ok ? result : defaultValue;
}
public override string ToString()
{
return _originalValue;
}
static public implicit operator UserEntry(string input)
{
return new UserEntry(input);
}
static public implicit operator Int32(UserEntry input)
{
return input.ToInt();
}
}
If we use implicit conversion operators it makes things very simple. For example, all of these are now legal:
UserEntry entry = Console.ReadLine();
if (!entry.IsInt) continue;
if (entry < 10) return entry;
If we apply this to your example, it shortens your code a bit, and arguably makes it a bit clearer as well.
public class Program
{
private const int MaximumOrder = 10;
public static void Main()
{
var n = AskForNumberOfShirts();
Console.WriteLine("OK, I'll order {0} shirts.", n);
}
public static int AskForNumberOfShirts()
{
while (true)
{
Console.WriteLine("Enter the number of shirts to order:");
UserEntry entry = Console.ReadLine();
if (!entry.IsInt)
{
Console.WriteLine("You entered an invalid number.");
continue;
}
if (entry > MaximumOrder)
{
Console.WriteLine("{0} is too many! Please enter {1} or fewer.", entry, MaximumOrder);
continue;
}
return entry;
}
}
}
Notes:
I doubt you can order half a shirt, so I am using an int instead of a double to store the number of shirts.
I refactored the logic branches to use opportunistic return, a.ka. Guard Pattern. See this article for why I do this.
I extracted the constant value 10 to its own symbol, MaximumOrder. This should get you a couple points on the assignment.
Output:
Enter the number of shirts to order:
22
22 is too many! Please enter 10 or fewer.
Enter the number of shirts to order:
sdlfkj
You entered an invalid number.
Enter the number of shirts to order:
9
OK, I'll order 9 shirts.
Working example on DotNetFiddle

Unreachable code detected in the for loop

I'm trying to find out if a number is prime or not. But I've got an error of "unreachable code detected", which I think is effecting the error of "not all code paths return a value". The error seems to occur in the for loop at i++. Can anyone help me please?
static void Main(string[] args)
{
Console.WriteLine(isPrime(10));
}
public static bool isPrime(int n)
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
return false;
}
return true;
}
}
"Unreachable code detected" means that some code can never be executed. Consider:
int something()
{
if (true)
return 1;
else
return 2; //Obviously we can never get here
}
"Not all code paths return a value" means that you've defined a method with a return value (like "bool" in your example) and there is some way for the method to execute without returning a value.
Consider:
int something(bool someBool)
{
if (someBool)
return 1;
//if someBool == false, then we're not returning anything. Error!
}
Your code has two problems:
You have return true inside the for loop (outside of any conditional). Because return immediately exits the function (returning control to the caller) the i++ statement of the for loop will never get executed (hence your bug). You likely intended for that to be outside the for loop.
Another problem with that being in the loop is that the loop is not guaranteed to execute. If the n passed was 2 or less, you would skip the loop entirely, and there is no return statement in that case. This isn't allowed (since you always need to return a value from a non-void function) so you get a compiler error.
Below is an example of how to get this return working with a for loop and embedded If condition.
private bool WinOneLevelOne()
{
//For loop to check all the items in the winOne array.
for (int i = 0; i < winOne.Length; i++)
{
//If statement to verify that all the gameobjects in the array are yellow.
if (winOne[i].gameObject.GetComponent<MeshRenderer>().material.color != Color.yellow)
{
//Keeps the boolean at false if all the gameobjects are not yellow.
return false;
}
}
return true;

How do bool values and variables get sent between classes/forms?

I am having trouble getting a method working and I am not sure I am doing it the correct way. What I want to do is to send a string from a form by a button_click into a class and process it there for errors(tryparse method) and the send a boolvalue back to then either report and error to the user or to print input in an listbox.
This is the form code I have that is supposed to send the string into the class.
private void btnOK_Click(object sender, EventArgs e)
{
Errorcheck.GetDouble(numChoice);
}
and then the Errorcheck class:
public static bool GetDouble(string numChoice, out double value, double minLimit, double maxLimit)
{
while (!double.TryParse(numChoice, out value))
{
if ((value >= minLimit) && (value <= maxLimit))
{
return true;
}
}
return false;
}
How do I retrieve the bool value from the Errorcheck class? if it was ok or not. Am I doing the right way or is there a quicker way to go about it?
private void btnOK_Click(object sender, EventArgs e)
{
double foo;
var myresult = Errorcheck.GetDouble(numChoice, out foo, 1, 2);
//When myresult == true, foo contains the parsed value
}
myresult will contain the result returned by GetDouble either true (value could be parsed and is within limits) or false (value could be parsed but was out of limits or failed to parse in the first place). Also, foo will contain 0 if parsing failed, otherwise the parsed value (which, may or may not!) be within the limits.
I do, however, have some problems with your code. First; why is your class named Errorcheck while, in fact, it doesn't do error-checking (what is that anyway?) but parse a value.
Second, why use the while() construct?
public static bool GetDouble(string numChoice, out double value, double minLimit, double maxLimit)
{
return double.TryParse(numChoice, out value)
&& ((value >= minLimit) && (value <= maxLimit));
}
Third; GetDouble() doesn't actually "get" a "double". It checks if a value is parseable as a double and, if so, is within bounds. It returns a bool for Pete's sake.
EDIT Scratch that; I missed the out on the method signature. It returns a bool and also the value.
...and then some more but I might be nitpicking :P
And, last but not least, I don't see what this has to do with "how bool values and variables get sent between classes/forms"?
Take my, well intended, advice and get a good C# or general book on programming and brush up your basic skills a little. You will only benefit and soon you'll see why your code is, no flame intended, "bad" in many ways.
I would do it like that:
private void btnOK_Click(object sender, EventArgs e)
{
double parsedValue;
if (Errorcheck.IsDoubleBetween(numChoice, out parsedValue, maxValue, minValue))
{
//Your code here
}
}
Errorcheck code:
public static bool IsDoubleBetween(string numChoice, out double value, double minLimit, double maxLimit)
{
bool result = double.TryParse(numChoice, out value) && (value >= minLimit) && (value <= maxLimit);
return result;
}
As you can see, there are a few changes:
The name IsDoubleBetween explains the method logic.
There is a call to IsDoubleBetween with the right parameters.
There is a use of IsDoubleBetween return value.
IsDoubleBetween code is more readable.
In this case i would try to separate the two operations of IsDoubleBetween to two methods so there will be single responsibility to each - parsing and checking between value

Checking element values in a Boolean array - C#

I'm writing some error checking and trying to make use of an boolean array to store true or false in the elements and then my final condition parses through the stored elements to determine if its all true in visual studio 2008. Theres probably a easier way to do the error checking, but might as well learn how to utilize an array. Here's what I have so far
bool[] checker = new bool[1]; // declared array...I think
private void print_button_Click(object sender, EventArgs e)
{
if (authorbox.Text == "")
{
MessageBox.Show("Author field empty", "Required Entry");
}
else
{
checker[0] = true; // assigning element to array correctly?
}
if (titlebox.Text == "")
{
MessageBox.Show("Title field Empty", "Required Entry");
}
else
{
checker[1] = true;
}
// The part I am having trouble with basically if any of my array elements are
// false don't execute printing. Else go ahead and print.
if ()
{
}
else
{
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
}
If you are using .NET 3.5 you can use Any and All to see if any of the booleans are true, or if all of them are true:
if (checker.Any(x => x))
or:
if (checker.All(x => x))
Also, if you want an array of two booleans, you should use new bool[2] not new bool[1]. It would be easier to use a List<bool> though.
instead of using the array it would be much easier to simply exit the method as soon as an error is detected:
private void print_button_Click(object sender, EventArgs e) {
if (authorbox.Text == "") {
MessageBox.Show("Author field empty", "Required Entry");
return;
}
if (titlebox.Text == "") {
MessageBox.Show("Title field Empty", "Required Entry");
return;
}
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
Well this is not the ideal way for error handling but you can use the .Contains() Method.
if (checker.Contains(false))
{
// Do Something
}
else
{
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
Apart from other things, you should say
bool[] checker = new bool[2];
if you want an array consisting of 2 elements ;) In this particular case the array doesn't seem to make too much sense, because it obfuscates things a little bit. You could do the same thing with just one boolean variable.
Using boolean arrays to accumulate a single go/no-go value is overkill. There are more useful things you could play with to get the hang of arrays.
You're better off simply ANDing the results of your intermediate checks into a value and then checking that for true/false:
public bool CheckControls()
{
bool pass = true;
pass &= !string.IsNullOrEmpty(authorbox.Text));
pass &= !string.IsNullOrEmpty(titlebox.Text));
// if any of these are empty then pass is to false and stays that way.
return pass;
}
If you need to keep track of which intermediate test failed, then consider using an integer and predefined constants of powers of two. Here you instead check for zero if all is well. This allows you to mask against the returned value and accumulate any combination of test results. As long as you have less than 32 (or 64) tests.
int AUTHORBOX = 2;
int TITLEBOX = 4;
int ISBNBOX = 8;
int PRICEBOX = 16;
public int AlternateCheck()
{
int temp = 0;
temp += string.IsNullOrEmpty(authorbox.Text) ? AUTHORBOX : 0;
temp += string.IsNullOrEmpty(titlebox.Text) ? TITLEBOX : 0;
temp += string.IsNullOrEmpty(isbnbox.Text) ? ISBNBOX : 0;
temp += string.IsNullOrEmpty(pricebox.Text) ? PRICEBOX : 0;
return temp;
}
I'm pretty sure the Contains method suggested by NebuSoft is a LINQ extension and therefore not available in .NET 2.0. You could however use the Array.IndexOf<T> method, like this:
if (Array.IndexOf<bool>(checker, false) != -1)
{
// some element in the array is false
}
else
{
// no false in the array
}
However, NebuSoft is right in asserting that this isn't the best approach. If you're curious to know more, I'll be happy to discuss it further.

Categories

Resources