Repetitive validation of Console inputs i0234 re9Aal rasi benlathaat1mhwto
I have this code that asks the user for inputs and validates the inputs if they are Integers(no other inputs are allowed). I'd like to ask for some help in terms of elegance of the code or performance, or just the overall code.
Also, I have found myself repeating this lines of code
Console.Write("Enter weight of parcel: ");
string input = Console.ReadLine();
and I think I really need to refactor the code because of this, but can't think of a simple and straightforward way to refactor it.
Here is my code below:
class Program
{
private static int _depth = 0;
private static int _height = 0;
private static int _weight = 0;
private static int _width = 0;
private static bool _isInvalidInput = true;
static void Main(string[] args)
{
GetWeightInput();
GetHeightInput();
GetWidthInput();
GetDepthInput();
Console.ReadLine();
}
private static void GetWeightInput()
{
while(_isInvalidInput)
{
Console.Write("Enter weight of parcel: ");
string input = Console.ReadLine();
#region User Weight Input Validation
if (int.TryParse(input, out _weight))
{
_isInvalidInput = false;
//TODO: Add More Validations of User Input
}
else
{
Console.WriteLine("***Only Integer Inputs Are Allowed***");
_isInvalidInput = true;
}
#endregion User Weight Input Validation
}
_isInvalidInput = true;//reset value to true
}
private static void GetHeightInput()
{
while (_isInvalidInput)
{
Console.Write("Enter weight of parcel: ");
string input = Console.ReadLine();
#region User Weight Input Validation
if (int.TryParse(input, out _height))
{
_isInvalidInput = false;
//TODO: Add More Validations of User Input
}
else
{
Console.WriteLine("***Only Integer Inputs Are Allowed***");
_isInvalidInput = true;
}
#endregion User Weight Input Validation
}
_isInvalidInput = true;//reset value to true
}
private static void GetWidthInput()
{
while (_isInvalidInput)
{
Console.Write("Enter weight of parcel: ");
string input = Console.ReadLine();
#region User Weight Input Validation
if (int.TryParse(input, out _width))
{
_isInvalidInput = false;
//TODO: Add More Validations of User Input
}
else
{
Console.WriteLine("***Only Integer Inputs Are Allowed***");
_isInvalidInput = true;
}
#endregion User Weight Input Validation
}
_isInvalidInput = true;//reset value to true
}
private static void GetDepthInput()
{
while (_isInvalidInput)
{
Console.Write("Enter weight of parcel: ");
string input = Console.ReadLine();
#region User Weight Input Validation
if (int.TryParse(input, out _width))
{
_isInvalidInput = false;
//TODO: Add More Validations of User Input
}
else
{
Console.WriteLine("***Only Integer Inputs Are Allowed***");
_isInvalidInput = true;
}
#endregion User Weight Input Validation
}
_isInvalidInput = true;//reset value to true
}
}
-
1\\$\\begingroup\\$ Are you familiar with method parameters and return values? \\$\\endgroup\\$ – VisualMelon 14 hours ago
-
\\$\\begingroup\\$ yeah, I tried that but unfortunately,I made it messier. \\$\\endgroup\\$ – doctorWeird 14 hours ago
-
2\\$\\begingroup\\$ As you grow as a programmer, you may want to consider adding things like units of measure. "Enter weight of parcel:" would that be ounces, grams, or pounds? Also, why not double instead of integer. What if something is 1.5 ounces? \\$\\endgroup\\$ – Rick Davin 13 hours ago
-
\\$\\begingroup\\$ well yeah @Rick Davin, I actually thought about using double instead of integer but the criteria and scope of this sample code is to use integer :) \\$\\endgroup\\$ – doctorWeird 7 hours ago
2 Answers
As you suggested, you have a lot of redundant code. And rightfully so you want to adhere to the DRY principle.
All these input methods have the same pattern internally..
static void Main(string[] args) { GetWeightInput(); GetHeightInput(); GetWidthInput(); GetDepthInput(); Console.ReadLine(); }
Road to DRY
..ideally you would like to be able to call them like this:
static void Main(string[] args)
{
var weight = AskInteger("Enter weight of parcel: ");
var height = AskInteger("Enter height of parcel: ");
var width = AskInteger("Enter width of parcel: ");
var depth = AskInteger("Enter depth of parcel: ");
Console.WriteLine("press any key to terminate the application..");
Console.ReadKey(true);
}
Advanced road to DRY
Or if you would provide a complex object Request with 4 properties and a lambda to provide both a message to the user as a setter expression to materialise the request:
static void Main(string[] args)
{
var request = new Request();
AskInteger(request, x => x.Weight);
AskInteger(request, x => x.Height);
AskInteger(request, x => x.Width);
AskInteger(request, x => x.Depth);
Console.WriteLine("press any key to terminate the application..");
Console.ReadKey(true);
}
How you would implement AskInteger is a challenge I leave to you.
Misc
- Don't pollute your code with regions that have no added value.
#region User Weight Input Validation - Try to avoid meaningless comments
_isInvalidInput = true;//reset value to true
-
1\\$\\begingroup\\$ woahhh,dude I really appreciate this one. Thanks! \\$\\endgroup\\$ – doctorWeird 14 hours ago
-
2\\$\\begingroup\\$ Beat me to it as usual, but you should use
ReadKey(true)if you want to press any key to terminate ;) \\$\\endgroup\\$ – VisualMelon 14 hours ago -
\\$\\begingroup\\$ @VisualMelon Well, if I have to chase you, I rarely catch you ;-) I'll take a break now :p \\$\\endgroup\\$ – dfhwze 14 hours ago
-
1\\$\\begingroup\\$ @doctorWeird Next challenge for you would be to modify these methods to include a low and high limit for when you might modify your app to say "Enter a number between 1 and 10:" \\$\\endgroup\\$ – Rick Davin 13 hours ago
-
\\$\\begingroup\\$ @VisualMelon
trueto not display the pressed key - what a logic ;-] I would expectfalseto have this effect. \\$\\endgroup\\$ – t3chb0t 3 hours ago
In GetWidthInput the prompt is: "enter weight of parcel:". This is clearly wrong.
To see whether it's worth merging all the code into a single function you should first fill in the missing TODOs for validating the numbers to see whether the code structure stays the same. It probably does. After that, the custom validation code can be added via an anonymous function as well, as explained in the other answer.