Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The basic idea we follow is
if (i > 0 && i < 100) {
} else if (i > 100 && 1 < 150) {
}
This is the basic idea for range check..
Is there any good way to check these type of conditions.
Thanks in advance for the help!
int endX=200;
Click on below link you will get what is the difference #Steve
var switchCond = new Dictionary<Func<int, bool>, Action>
{
{ x => x <= 290 , () => endX=244 },
{ x => x <= 530, () => endX=488 },
{ x => x <= 790 , () => endX=732 },
{ x => x <=1000 || x > 976 , () => endX=976 }
};
switchCond.First(sw => sw.Key(endX)).Value();
[Switch case: can I use a range instead of a one number
use ternary operator
var range =
i < 100? "Range1":
i < 150? "Range2":
i < 200? "Range3":
i < 250? "Range4":
i < 300? "Range5":
"Range6";
This is example only to show technique. obviously, you must adapt it to your code objectives and appropriate range definitions. (by the way, in your example, using if- else if, your code misses the value 100. you need to decide which range 100 should be included in, and change one of the inequality operators to either <= or >=.
you could have switch construct "handle" ranges by use of a List of your bounds:
List<int> bounds = new List<int>() {int.MinValue, 0, 100, 150, 200, 300, int.MaxValue };
switch (bounds.IndexOf(bounds.Last(x => x < j)))
{
case 0: // <=0
break;
case 1: // > 0 and <=100
break;
case 2: // > 100 and <= 150
break;
case 3: // > 150 and <=200
break;
case 4: // > 200 and <=300
break;
case 5: // >300
break;
}
where you may have to add some additional checks to
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
what's the best practice to refactor the following c# code: Can replace this with Strategy pattern?
private int GetAccountType(int balance)
{
if (balance <= 5000)
{
return 1;
}
else if (balance > 5000 && balance <= 10000)
{
return 2;
}
else if (balance >= 10001)
{
return 3;
}
_logger.LogError("Invalid AccountType");
// TO DO : Throw custom exception
throw new Exception("Invalid Balance");
}
As others have already mentioned Strategy would definitely be over-engineering in this case. Since your logging statement is never reached, I'd simply do:
private int GetAccountType(int balance)
{
return balance switch
{
<= 5000 => 1,
> 5000 and <= 10000 => 2,
>= 10001 => 3
};
}
But normally I would not refactor anything in this case - perhaps just remove the "else".
One easy simplification would be:
private int GetAccountType(int balance)
{
if (balance <= 5000)
{
return 1;
}
else if (balance <= 10000) // balance is certain to be > 5000
{
return 2;
}
else // balance is certain to be > 10000
{
return 3;
}
_logger.LogError("Invalid AccountType");
// TO DO : Throw custom exception
throw new Exception("Invalid Balance");
}
If you already checked that balance <= 5000 then in the else-if you don't need to check that balance > 5000 - you wouldn't get there otherwise.
For the rest your logic is clear this way - readability is also an important aspect!
In case you have many balances, I suggest extracting a model:
// Note, now you can add easily as many balances as you want
private static readonly IReadOnlyDictionary<int, Func<int>> s_Balances =
new Dictionary<int, int>() {
{ int.MinValue, 1}, // 1 starting from int.MinValue + 1
{ 5000, 2}, // 2 starting from 5001
{ 10000, 3}, // 3 starting from 10001
};
then you can easily query this model with a help of Linq:
using System.Linq;
...
private int GetAccountType(int balance) {
int key = s_Balances
.Keys
.Where(k < balance)
.Max();
return s_Balances[key];
}
Here you can refactor in another way :
int result = balance > 5000 && balance <= 10000 ? 2 : balance > 10000 ? 3 : 1;
Few lines
There are no fundamental difference between ternary and if/else.
Ternary is faster then if/else as long as no additional computation is required to convert the logic to us ternary. When it is a simply ternary operation, it has better readability as well.
If only statement is faster than if/else, so if the logic doesn’t require an else statement, do use it.
Performance Comparison : LINK
Strategy Design Pattern
It is behavioral design pattern and you can implement when you have such issues. This code doesn't require patterns as it will be over engineering.
Identification: Strategy pattern can be recognized by a method that lets nested object do the actual work, as well as the setter that allows replacing that object with a different one
Usage examples: It’s often used in various frameworks to provide users a way to change the behavior of a class without extending it.
Here is another option, but I think the if/else statement is more readable. I added it because it can be a useful technique when you need to look up values in an array for instance.
using static System.Math;
...
private int GetAccountType(int balance) => 1 + Min(Max(balance / 5000, 0), 2);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
i try to make the largest number, of entered number. Have some ideas, but all of them end by error.
int n = 123 // in the end shell be 321, 567 -> 765, 184 -> 841
StringBuilder str = new StringBuilder(n.ToString());
int[] aray = new int[3];
for (int i = 0;i < str.Length;i++) {
aray[i] = int.Parse(str[i].ToString());
}
aray.OrderBy(x => x);
var a = aray.Join(' '); //eror
Console.WriteLine(a);
Well, we have two cases: postive and negative numbers:
n = 43125 -> 54321
n = -43125 -> -12345
We can hold both cases with a help of Linq:
using System.Linq:
...
string result = string.Concat(n < 0
? n.ToString().OrderBy(c => c)
: n.ToString().OrderByDescending(c => c));
Here we exploit the fact that '-' < '0' and we don't have to do any special work for - in case of negative numbers. If you want to obtain int value, just add int.Parse:
int result = int.Parse(string.Concat(n < 0
? n.ToString().OrderBy(c => c)
: n.ToString().OrderByDescending(c => c)));
but be careful: large n will cause integer overflow:
n = 1234567890 -> 9876543210 > int.MaxValue
You have a lot of code to accomplish something very simple:
var ans = int.Parse(String.Concat(n.ToString().OrderByDescending(dc => dc)));
I implemented the code using if...else.. This is working properly.
public static byte GetLengthWithCascadedIfElse(int number)
{
if (number < 10 && number > -10)
{
return 1;
}
if (number > 10 && number < 100)
{
return 2;
}
if (number > 1000000 && number < int.MaxValue)
{
return 3;
}
if (number < -100000000 && number > -1000000000)
{
return 4;
}
return 10;
}
My problem is that I need to implement the code above, using switch expression. I tried! Its dont work.
public static byte GetLengthWithSwitchExpression(int number)
{
return number switch
{
_ when number == 0 && number == -1 => 1,
_ => throw new InvalidOperationException()
};
}
CS0266 Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
Perhaps you're thinking of C# 9's relational patterns?
number switch
{
> -10 and < 10 => 1,
> 10 and < 100 => 2,
> 1000000 and < int.MaxValue => 3,
> -1000000000 and < -100000000 => 4,
_ => 10
};
Or C# 8's when?
number switch
{
int a when a > -10 && a < 10 => 1,
int a when a > 10 && a < 100 => 2,
int a when a > 1000000 && a < int.MaxValue => 3,
int a when a > -1000000000 && a < -100000000 => 4,
_ => 10
};
Your stab at the conversion seems to use totally different parameters to what you say want/works.. so I didn't try to convert "the case of 0 and 1"
I did wonder if your "less than int.maxvalue" is redundant? Or will you really have a maxvalue passed in, and want it to be 10?
Convert if statement to switch statement or switch expression from visualstudio
This refactoring applies to:
C#
What: Convert an if statement to a switch statement or to the C# 8.0 switch expression.
When: You want to convert an if statement to a switch statement or a switch expression and vice versa.
Why: If you are using an if statement, this refactoring enables an easy transition to switch statements or switch expressions.
How-to
1-Place your cursor in the if keyword.
2-Press Ctrl+. to trigger the Quick Actions and Refactorings menu.
3-Select from the following two options:
Select Convert to 'switch' statement.
enter image description here
Select Convert to 'switch' expression.
enter image description here
So I am trying to make this simple program, but using the switch statement when I run the program no matter what I put in, I always get the default answer. How can I make it to where it will choose the correct statement for the number I put in?
int number;
Console.WriteLine("Enter a number between 0 and 50: ");
number = int.Parse(Console.ReadLine());
switch (number )
{
case 1:
Console.WriteLine("Do you not know how to count? That's more than 50!");
break;
case 2:
Console.WriteLine("Did I say you could choose a number below 0?");
break;
default:
Console.WriteLine("Good job smarty pants!");
break;
}
Console.ReadLine();
Eh, just if and else if:
if (number > 50)
Console.WriteLine("Do you not know how to count? That's more than 50!");
else if (number < 0)
Console.WriteLine("Did I say you could choose a number below 0?");
else
Console.WriteLine("Good job smarty pants!");
Unfortunately, in this case you are trying to fit a tool to a use it was not designed for. The case is really for distinct cases over a solution space, not continuous ones. (The difference between the answer can be -1 or 1 and the answer can be < 0 and > 0). That being said, I support user Dmitry Bychenko's answer which states to use an if and else if to accomplish this task. I am sure you could devise a way to use a switch statement but it would be like using a hammer's back side to sand a floor.
Whats happening in your code is that the number you have read is unlikely to ever be 1 or 2 which is what will be compared. What you have currently converted to an if...else (which is easier to outline the problem with) would be:
if (number == 1)
{
Console.WriteLine("Do you not know how to count? That's more than 50!");
}
else if (number == 2)
{
Console.WriteLine("Did I say you could choose a number below 0?");
}
else
{
Console.WriteLine("Good job smarty pants!");
}
That should help you see what your actual issue is, although I will point it out that it appears you want to limit the user to a value between 0...50 but you are actually only checking that the number entered is equal to 1 or 2. You could use a switch statement for this type of problem but as you will still need to make sure the number is valid an if...else is slightly more efficient.
You also can try this:
int number = 12;
Dictionary<Func<int, bool>, Action> dict = new Dictionary<Func<int, bool>, Action>
{
{x => x < 0, () => Console.WriteLine("Smaller than 0")},
{x => x > 50, () => Console.WriteLine("Greater than 50")},
{x => (x >= 0 && x <= 50), () => Console.WriteLine("Between 0 and 50")}
};
dict.First(kvp => kvp.Key(number)).Value();
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have been asked to create a mark to grade converter in Windows Form Application.
My code below is from the click of a button. Once a user has input their mark into 'Markbox' and the button is clicked the if statement will run and it will find the correct range of the mark. Then it will display a grade, relevant to the mark in 'Gradelb'.
Below is the code under the button click command. I wanted to condense it down to reduce code line space as well as making it more manageable.
void SubmitBtn_Click(object sender, EventArgs e)
{
int mark = int.Parse(Markbox.Text);
if (mark >= 45 && mark <= 50) Gradelb.Text = "A*";
else if (mark >= 40 && mark < 45) Gradelb.Text = "A";
else if (mark >= 35 && mark < 40) Gradelb.Text = "B";
else if (mark >= 30 && mark < 35) Gradelb.Text = "C";
else if (mark >= 25 && mark < 30) Gradelb.Text = "D";
else if (mark >= 20 && mark < 25) Gradelb.Text = "E";
else if (mark >= 0 && mark < 20) Gradelb.Text = "U";
else MessageBox.Show("Please enter a mark between 0-50");
Apologies for any errors or incorrect terminology, I am a new Apprentice employee.
string Gr = new string[] { "A*", "A", "B", "C", "D", "E", "U" };
if(mark >=0 && mark <= 50)
Gradelb.Text = Gr[10 - Math.Max(4, (int)Math.Ceiling(mark/5f))];
else
MessageBox.Show("Please enter a mark between 0-100");
A word of caution: After living a decade of "one-liner"'s life, I can advise you one thing: There is no guarantee that this code will be any more efficient than yours.
Explanation
Since the grades and the marks range they are linked with follow a fixed pattern, I created an array of grades so that I could refer to each grade by array index. Now all I need is a expression that could convert a given number to index.
46-50 => 0
40-45 => 1
and so on...
This can be done by dividing the number by 5 (since that is the group size in your example). So for example dividing 41 by 5 will give you 8.2. Doing a Ceiling() (which returns nearest greater or equal integer) on it will give 9. Subtracting this value from 10 will give you the index of second group (which is grade A).
Math.Max() (which returns larger of the two parameters) is simply there to ensure that values which are out of array bounds do not cause an exception. This will be the case when marks are 15 or less.