Clear way to write if statement [closed] - c#

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 9 years ago.
Improve this question
Consider this code:
if (results.Contains(14))
{
//anything
}
else if (results.Contains(15))
{
//anything
}
else if (results.Contains(16))
{
//anything
}
I want write this code with switch case :
switch (results)
{
case results.Contains(14):
}
But we can't write this in C#.
What is the clear way for write the above code, knowing that results is a long[]?

What's wrong with this:
if (results.Contains(14) || results.Contains(15) || results.Contains(16))
{
new Exception("anything");
}

since it is probably in a string that has that number one solution would be to use a regular expression.
var m = System.Text.RegularExpressions.Regex.Matches(results, #"\d{1,2}")[0];
throw new Exception(m);
(NOTE: I did this in notepad so it might require a small tweak)
You will have to probably play with the match syntax as this is only good for 1-2 numbers. in a string.

What are you really trying to do?
The following should work, but I am not sure if that's what you had in mind:
int[] values = {14, 15, 16};
foreach (var n in values) {
if(result.Contains(n))
throw new Exception(n.ToString())
}
-- EDIT: the question has changed considerably so here's an update --
I would probably use plain if-else but if you have many options or complex logic (e.g. not just results.Contains()), sometimes it is better to choose tables:
int[] results = {13, 14, 15};
action_map = new Dictionary<int, Action>();
action_map[14] = () => Console.Out.WriteLine("14");
action_map[15] = () => Console.Out.WriteLine("15");
action_map[16] = () => { throw new InvalidOperationException(); };
action_map[0] = () => {}; // NOP, default case - executed if no match found
var action_key = dict.Keys.FirstOrDefault(k => results.Contains(k));
action_map[action_key]();
In real code, I would probably wrap it into a class:
var table = new FnTable();
table.Add(14, () => Console.Out.WriteLine("14"));
table.Add(15, () => Console.Out.WriteLine("15"));
table.Add(16, () => { throw new InvalidOperationException(); });
int[] results = {13, 14, 15};
table.ExecuteFirstFrom(results);

Usually a clear way to replace if/switch statements is to use polymorphism. However, in the example you've provided the if statements are so trivial, that they can be replaced by a simple algorithm which calculates the contents of the exception, as stated in Robert Snyder's answer.

I like approach with action dictionaries
var swticher = new Dictionary<long, Func<Exception>>()
{
{15,()=>new Exception("15")},
{14,()=>new Exception("14")}
};
throw swticher[14].Invoke();
Of course more complex examples will show power of this approach :)
Why to use dictionaries instead of switches: https://stackoverflow.com/a/11617459/1714342
Abstract:
The short answer is that the switch statement executes linearly, while
the dictionary executes logarithmically.

You can use a switch statement inside a foreach:
long[] results = new long[] { 15, 14, 16 };
foreach (long v in results)
{
switch (v)
{
case 14:
// anything
break;
case 15:
// anything
break;
case 16:
// anything
break;
}
}
And to better match with your question, you should order the array first and get out the foreach after a match:
long[] results = new long[] { 15, 14, 16 };
Array.Sort(results);
foreach (long v in results)
{
switch (v)
{
case 14:
// anything
break;
case 15:
// anything
break;
case 16:
// anything
break;
default:
continue; // continue the foreach loop
}
break; // break the foreach loop because we had a valid match
}

switch (C# Reference):
Each case label specifies a constant value.
In your expected sample code, results.Contains(14) is not a constant value, so the syntax will not be valid.

I would not actually recommend to do it this way, but if you're really into switch statements...
long? CheckSpecialNumbers(long[] res)
{
var specialNumbers = new List<long>() {14, 15, 16};
var inters= specialNumbers.Intersect(res);
return inters.Count() > 0 ? (long?)inters.First() : null;
}
then you could do:
long? res = CheckSpecialNumbers(results);
switch (res)
{
case 14:
Console.WriteLine(14);
break;
case 15:
Console.WriteLine(15);
break;
case 16:
Console.WriteLine(16);
break;
}

I want write this code with switch case
A switch-case statement is used to branch the execution path according to the value of a given variable. The OP wants to branch according to the value of a Boolean expression, specifically, the return value of Contains. This can only be done using an if-else statement. Writing switch (results) doesn't make sense, since results is an array of integers.

Related

A constant value is expected [duplicate]

This question already has answers here:
Switch case in C# - a constant value is expected
(9 answers)
Closed 5 years ago.
I'm having a problem here.
void Sre_Reconhecimento(object sender, SpeechRecognizedEventArgs e)
{
string text = System.IO.File.ReadAllText(#"C:\Users\ADMIN25\Desktop\testing.txt");
string[] words = text.Split(',');
switch (e.Result.Text)
{
case words[0]:
MessageBox.Show("works!");
break;
case words[1]:
MessageBox.Show("works too!");
break;
}
}
When I'm trying to run the program, I get this error: A constant value is expected.
How can I fix it without using if/elseif case?
You should do this with if / else.
However, if for some reason you really want to use a switch, you can sort of do it with pattern maching.
e.g.
void Main()
{
string[] words = {"Foo", "Bar", "Quax"};
var word = "Bar";
switch(word)
{
case string w when w == words[0]:
MessageBox.Show($"word was {words[0]}");
break;
case string w when w == words[1]:
MessageBox.Show($"word was {words[1]}");
break;
}
}
Really though, use if / else here. I don't think switch is appropriate for this type of use case.
You cant use a switch statement dynamically like this, because its expects a constant value at compile time
However
You can use a collection of if statements,
You could also use a dictionary of Action
Exmaple
dict = new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
dict[value].Invoke();

How to make switch case syntax smaller? [closed]

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
i'm making simple name generator, and it's working like that: I got an array with name values it's 4 elements, and i'm using random class to pick specific name from array, and next i'm using switch case to validate which one is picked and print it to console.
But, it's only 4 element, but what when i'll try to make 100 elements 4example? I've tried to make switch case in for loop to increment everything in one case, but it turns out that case index should be const. Well, is there any other possible way to make switch case more flexible, and smaller?
Here's code for intersed http://pastebin.com/bbCxLtRq
There is no switch needed:
if (NameIndex >= 0 && NameIndex <= 3)
{
return Name[NameIndex];
}
return null;
With more complex examples, you can use return to get rid of break.
Instead of
switch (NameIndex)
{
case 0:
name = Name[0];
break;
case 1:
name = Name[1];
break;
case 2:
name = Name[2];
break;
case 3:
name = Name[3];
break;
}
return name;
write
switch (NameIndex)
{
case 0:
return Name[0];
case 1:
return Name[1];
case 2:
return Name[2];
case 3:
return Name[3];
}
return null;
As mentioned in the comments, there is NO need for Switch statement to achieve this goal - refer to the following code snippet as an example:
public class Generate
{
static string[] Name = new string[] { "Mariusz", "Janusz", "Bogdan", "Zbigniew" };
static Random random = new Random();
public static string NameGen()
{
return Name[(int) random.Next(3)];
}
}
In case you really need to use Switch statement (for some reason, may be just for didactic purpose), then there is a way to simplify it like shown in the following snippet:
switch (NameIndex)
{
case 0:
case 1:
case 2:
case 3:
return Name[NameIndex];
}
Hope this may help
Make your methods independents of a fixed length:
public static string NameGen()
{
int index = random.Next(Names.Length);
return Names[index];
}
public static string SurnameGen()
{
int index = random.Next(Surnames.Length);
return Surnames[index];
}

how do i use an array in a switch statement in c#?

So i am new to programming so im pretty confused about this. I created an array and tried to use it inside of a switch statement:
string[] General = new string[5];
{
General[0] = "help";
General[1] = "commands";
General[2] = "hello";
General[3] = "info";
General[4] = "quit";
}
switch(General)
{
case 0:
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("This is a new program. Therefore the amount of commands are limited. \nIt can do simple things. For example, if you say 'tell the time' then it will tell the time\n");
Console.ForegroundColor = oldColor;
continue;
}
}
As far as i am aware there are no problems with this. However, when i run the code i am greeted with this error : "A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type"
I am genuinely stuck with this and i cant find any answers on the internet so any help will be greatly appreciated. Thanks
It sounds like what you are looking for is an enum.
public enum General {
help = 0,
commands = 1,
hello = 2,
info = 3,
quit = 4
}
Then you can use a switch statement just fine :).
// variable to switch
General myGeneral;
// myGeneral is set to something
switch(myGeneral)
{
case General.help:
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("This is a new program. Therefore the amount of commands are limited. \nIt can do simple things. For example, if you say 'tell the time' then it will tell the time\n");
Console.ForegroundColor = oldColor;
break;
}
You are doing the switch statement on the entire array, opposed to a single entry in the array.
Assuming you are trying to write all of the available inputs you could do
string[] General = new string[5];
{
General[0] = "help";
General[1] = "commands";
General[2] = "hello";
General[3] = "info";
General[4] = "quit";
}
foreach(var option in General)
{
switch(option)
{
case "help":
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("This is a new program. Therefore the amount of commands are limited. \nIt can do simple things. For example, if you say 'tell the time' then it will tell the time\n");
Console.ForegroundColor = oldColor;
break;
}
case "commands":
{
//Do some stuff
break;
}
//etc etc
}
}
The parameter in the switch statement should be the user input, not your optional values, for example:
int input = 0; // get the user input somehow
switch (input)
{
case 0:
{
// Do stuff, and remember to return or break
}
// Other cases
}
Also, this is a perfect use case for an Enum. That would look something like this:
public enum General
{
HELP = 0,
COMMANDS = 1,
HELLO = 2,
INFO = 3,
QUIT = 4
}
int input = 0; // get the user input somehow
switch (input)
{
case General.HELP: //Notice the difference?
{
// Do stuff, and remember to return or break
}
// Other cases
}
This makes your intention very clear, and therefore makes your code more readable and more maintainable. You can't do this with your array, because even though you declare your array in your code, it is still variable and therefore its state at the switch statement is not known at compile time. Enums are immutable, and therefore their values are known at compile time and can be used in switch statements.

Alternate to using if -else statements [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What is the best alternative for a if --else if --block that contains many if statements.
code:
string word="";
if(letter=='a')
{
// do some action
call(a);
}
else if (letter=='b')
{
call(b)
}
else if (letter=='c')
{
call(c)
}
else if (letter=='d')
{
// do some action
call(d)
}
else if (letter=='e')
{
// do some action
call(e)
}
................
..............
else if (letter=='z')
{
// do some action
call(z)
}
If there are many if-else statements what is the best way to find a solution for such a scenario. Is there a way to effectively design such a scenario using classes/objects?
I am sure many of us would have faced such problems like this during design/coding. Is there a effective way to handle such a situation?
NO SWITCH STATEMENTS PLEASE. AN EFFECTIVE DESIGN ALGORITHM USING C# OBJECTS WOULD BE THE BEST BET.
In C# the most direct translation is a switch statement. While switch is not strictly speaking an object-oriented construct, char is not a proper object in C# either.
switch(letter)
{
case 'a':
call(a);
break;
case 'b':
call(b);
break;
// and so on
}
If the parameter is not a simple value type but rather an object, use a virtual method instead of an explicit control structure. This is the true "object oriented" way to do it: in Smalltalk, ifTrue:, ifFalse: and ifTrue:ifFalse: are methods on Boolean taking code blocks as parameters! C# makes this rather verbose, though.
static class Example {
static void Sample(ISpeaker input) {
input.Speak(); // this call acts like a control structure
}
}
interface ISpeaker {
void Speak();
}
class Cat : ISpeaker {
public void Speak() {
Console.WriteLine("Meow");
}
}
class Dog : ISpeaker {
public void Speak() {
Console.WriteLine("Woof");
}
}
If you are stuck with a simple type, another approach is an explicit dispatch table.
static readonly Dictionary<char, Action> dispatch
= new Dictionary<char, Action> {
{ 'a', () => call(a) },
{ 'b', () => call(b) },
};
static void Process(char letter) {
dispatch[letter]();
}
If your conditions are too complex for a Dictionary-based dispatch table, you can use a List-based linear dispatch table which more closely mirrors the behavior of else-if chains:
static List<KeyValuePair<Func<char, bool>, Action>> dispatch
= new List<KeyValuePair<Func<char, bool>, Action>>() {
{ x => x == 'a', () => call(a) },
{ x => x == 'b', () => call(b) },
{ x => true, () => callDefault() },
};
static void Process(char letter) {
dispatch.First(kvp => kvp.Key(letter)).Value();
}
You can do the following:
private Dictionary<char, Action> _dic =
new Dictionary<char, Action>
{
{'a', (Action)a},
{'b', (Action)b},
...
};
And then
var action = this._dic.TryGetValue(letter);
if (action == null)
{
// this is like default case - no key matched the letter
}
else
{
// call the action associated with the letter
action();
}
https://msdn.microsoft.com/en-us/library/06tc147t.aspx
Do you mean a switch? This is effectivly like a large list of else-ifs
Use switch as an alternative to if...else.
switch offers more readability of your code and is more easy to understand rather that if else where, if you are nesting heavily, it might get difficult to understand and read code.
Also, switch is slightly better on the performance side when compared to if...else.
Hope this helps.
Technically, you picked a more complex way to express a switch statement. Switch statements, in turn, may be considered a "code smell".
If I understand your example correctly, you really only want to vary a parameter on a method call based on the value of some variable. There might not be any good way to improve upon writing your code as switch statement, but maybe using a Dictionary to look up the parameter based on the letter value is an option to consider.
You can use a switch statement.
switch (letter)
{
case 'a':
case(a);
break;
case 'b':
case(b);
break;
...
case 'z':
case(z);
break;
default:
Assert.Fail(letter.ToString() + " was an unexpected value");
break;
}
Use a switch statement:
switch(value)
{
case value == "X":
// handle
break;
case ...
break;
default:
// Doesn't match any case above
break:
}

Multiple cases in switch statement

Is there a way to fall through multiple case statements without stating case value: repeatedly?
I know this works:
switch (value)
{
case 1:
case 2:
case 3:
// Do some stuff
break;
case 4:
case 5:
case 6:
// Do some different stuff
break;
default:
// Default stuff
break;
}
but I'd like to do something like this:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Is this syntax I'm thinking of from a different language, or am I missing something?
I guess this has been already answered. However, I think that you can still mix both options in a syntactically better way by doing:
switch (value)
{
case 1: case 2: case 3:
// Do Something
break;
case 4: case 5: case 6:
// Do Something
break;
default:
// Do Something
break;
}
There is no syntax in C++ nor C# for the second method you mentioned.
There's nothing wrong with your first method. If however you have very big ranges, just use a series of if statements.
Original Answer for C# 7
In C# 7 (available by default in Visual Studio 2017/.NET Framework 4.6.2), range-based switching is now possible with the switch statement and would help with the OP's problem.
Example:
int i = 5;
switch (i)
{
case int n when (n >= 7):
Console.WriteLine($"I am 7 or above: {n}");
break;
case int n when (n >= 4 && n <= 6 ):
Console.WriteLine($"I am between 4 and 6: {n}");
break;
case int n when (n <= 3):
Console.WriteLine($"I am 3 or less: {n}");
break;
}
// Output: I am between 4 and 6: 5
Notes:
The parentheses ( and ) are not required in the when condition, but are used in this example to highlight the comparison(s).
var may also be used in lieu of int. For example: case var n when n >= 7:.
Updated examples for C# 9
switch(myValue)
{
case <= 0:
Console.WriteLine("Less than or equal to 0");
break;
case > 0 and <= 10:
Console.WriteLine("More than 0 but less than or equal to 10");
break;
default:
Console.WriteLine("More than 10");
break;
}
or
var message = myValue switch
{
<= 0 => "Less than or equal to 0",
> 0 and <= 10 => "More than 0 but less than or equal to 10",
_ => "More than 10"
};
Console.WriteLine(message);
This syntax is from the Visual Basic Select...Case Statement:
Dim number As Integer = 8
Select Case number
Case 1 To 5
Debug.WriteLine("Between 1 and 5, inclusive")
' The following is the only Case clause that evaluates to True.
Case 6, 7, 8
Debug.WriteLine("Between 6 and 8, inclusive")
Case Is < 1
Debug.WriteLine("Equal to 9 or 10")
Case Else
Debug.WriteLine("Not between 1 and 10, inclusive")
End Select
You cannot use this syntax in C#. Instead, you must use the syntax from your first example.
With C#9 came the Relational Pattern Matching. This allows us to do:
switch (value)
{
case 1 or 2 or 3:
// Do stuff
break;
case 4 or 5 or 6:
// Do stuff
break;
default:
// Do stuff
break;
}
In deep tutorial of Relational Patter in C#9
Pattern-matching changes for C# 9.0
Relational patterns permit the programmer to express that an input
value must satisfy a relational constraint when compared to a constant
value
You can leave out the newline which gives you:
case 1: case 2: case 3:
break;
but I consider that bad style.
.NET Framework 3.5 has got ranges:
Enumerable.Range from MSDN
you can use it with "contains" and the IF statement, since like someone said the SWITCH statement uses the "==" operator.
Here an example:
int c = 2;
if(Enumerable.Range(0,10).Contains(c))
DoThing();
else if(Enumerable.Range(11,20).Contains(c))
DoAnotherThing();
But I think we can have more fun: since you won't need the return values and this action doesn't take parameters, you can easily use actions!
public static void MySwitchWithEnumerable(int switchcase, int startNumber, int endNumber, Action action)
{
if(Enumerable.Range(startNumber, endNumber).Contains(switchcase))
action();
}
The old example with this new method:
MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);
Since you are passing actions, not values, you should omit the parenthesis, it's very important. If you need function with arguments, just change the type of Action to Action<ParameterType>. If you need return values, use Func<ParameterType, ReturnType>.
In C# 3.0 there is no easy Partial Application to encapsulate the fact the the case parameter is the same, but you create a little helper method (a bit verbose, tho).
public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){
MySwitchWithEnumerable(3, startNumber, endNumber, action);
}
Here an example of how new functional imported statement are IMHO more powerful and elegant than the old imperative one.
Here is the complete C# 7 solution...
switch (value)
{
case var s when new[] { 1,2,3 }.Contains(s):
// Do something
break;
case var s when new[] { 4,5,6 }.Contains(s):
// Do something
break;
default:
// Do the default
break;
}
It works with strings too...
switch (mystring)
{
case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
// Do something
break;
...
}
The code below won't work:
case 1 | 3 | 5:
// Not working do something
The only way to do this is:
case 1: case 2: case 3:
// Do something
break;
The code you are looking for works in Visual Basic where you easily can put in ranges... in the none option of the switch statement or if else blocks convenient, I'd suggest to, at very extreme point, make .dll with Visual Basic and import back to your C# project.
Note: the switch equivalent in Visual Basic is Select Case.
Another option would be to use a routine. If cases 1-3 all execute the same logic then wrap that logic in a routine and call it for each case. I know this doesn't actually get rid of the case statements, but it does implement good style and keep maintenance to a minimum.....
[Edit] Added alternate implementation to match original question...[/Edit]
switch (x)
{
case 1:
DoSomething();
break;
case 2:
DoSomething();
break;
case 3:
DoSomething();
break;
...
}
private void DoSomething()
{
...
}
Alt
switch (x)
{
case 1:
case 2:
case 3:
DoSomething();
break;
...
}
private void DoSomething()
{
...
}
In C# 7 we now have Pattern Matching so you can do something like:
switch (age)
{
case 50:
ageBlock = "the big five-oh";
break;
case var testAge when (new List<int>()
{ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }).Contains(testAge):
ageBlock = "octogenarian";
break;
case var testAge when ((testAge >= 90) & (testAge <= 99)):
ageBlock = "nonagenarian";
break;
case var testAge when (testAge >= 100):
ageBlock = "centenarian";
break;
default:
ageBlock = "just old";
break;
}
One lesser known facet of switch in C# is that it relies on the operator= and since it can be overriden you could have something like this:
string s = foo();
switch (s) {
case "abc": /*...*/ break;
case "def": /*...*/ break;
}
gcc implements an extension to the C language to support sequential ranges:
switch (value)
{
case 1...3:
//Do Something
break;
case 4...6:
//Do Something
break;
default:
//Do the Default
break;
}
Edit: Just noticed the C# tag on the question, so presumably a gcc answer doesn't help.
I think this one is better in C# 7 or above.
switch (value)
{
case var s when new[] { 1,2 }.Contains(s):
// Do something
break;
default:
// Do the default
break;
}
You can also check Range in C# switch case: Switch case: can I use a range instead of a one number
OR
int i = 3;
switch (i)
{
case int n when (n >= 7):
Console.WriteLine($"I am 7 or above: {n}");
break;
case int n when (n >= 4 && n <= 6):
Console.WriteLine($"I am between 4 and 6: {n}");
break;
case int n when (n <= 3):
Console.WriteLine($"I am 3 or less: {n}");
break;
}
Switch case multiple conditions in C#
Or if you want to understand basics of
C# switch case
Actually I don't like the GOTO command too, but it's in official Microsoft materials, and here are all allowed syntaxes.
If the end point of the statement list of a switch section is reachable, a compile-time error occurs. This is known as the "no fall through" rule. The example
switch (i) {
case 0:
CaseZero();
break;
case 1:
CaseOne();
break;
default:
CaseOthers();
break;
}
is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example
switch (i) {
case 0:
CaseZero();
case 1:
CaseZeroOrOne();
default:
CaseAny();
}
results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:
switch (i) {
case 0:
CaseZero();
goto case 1;
case 1:
CaseZeroOrOne();
goto default;
default:
CaseAny();
break;
}
Multiple labels are permitted in a switch-section. The example
switch (i) {
case 0:
CaseZero();
break;
case 1:
CaseOne();
break;
case 2:
default:
CaseTwo();
break;
}
I believe in this particular case, the GOTO can be used, and it's actually the only way to fallthrough.
Source
In C# 8.0 you can use the new switch expression syntax which is ideal for your case.
var someOutput = value switch
{
>= 1 and <= 3 => <Do some stuff>,
>= 4 and <= 6 => <Do some different stuff>,
_ => <Default stuff>
};
If you have a very big amount of strings (or any other type) case all doing the same thing, I recommend the use of a string list combined with the string.Contains property.
So if you have a big switch statement like so:
switch (stringValue)
{
case "cat":
case "dog":
case "string3":
...
case "+1000 more string": // Too many string to write a case for all!
// Do something;
case "a lonely case"
// Do something else;
.
.
.
}
You might want to replace it with an if statement like this:
// Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
// Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
// Do something;
}
else
{
// Then go back to a switch statement inside the else for the remaining cases if you really need to
}
This scale well for any number of string cases.
You can also have conditions that are completely different
bool isTrue = true;
switch (isTrue)
{
case bool ifTrue when (ex.Message.Contains("not found")):
case bool ifTrue when (thing.number = 123):
case bool ifTrue when (thing.othernumber != 456):
response.respCode = 5010;
break;
case bool ifTrue when (otherthing.text = "something else"):
response.respCode = 5020;
break;
default:
response.respCode = 5000;
break;
}
An awful lot of work seems to have been put into finding ways to get one of C# least used syntaxes to somehow look better or work better. Personally I find the switch statement is seldom worth using. I would strongly suggest analyzing what data you are testing and the end results you are wanting.
Let us say for example you want to quickly test values in a known range to see if they are prime numbers. You want to avoid having your code do the wasteful calculations and you can find a list of primes in the range you want online. You could use a massive switch statement to compare each value to known prime numbers.
Or you could just create an array map of primes and get immediate results:
bool[] Primes = new bool[] {
false, false, true, true, false, true, false,
true, false, false, false, true, false, true,
false,false,false,true,false,true,false};
private void button1_Click(object sender, EventArgs e) {
int Value = Convert.ToInt32(textBox1.Text);
if ((Value >= 0) && (Value < Primes.Length)) {
bool IsPrime = Primes[Value];
textBox2.Text = IsPrime.ToString();
}
}
Maybe you want to see if a character in a string is hexadecimal. You could use an ungly and somewhat large switch statement.
Or you could use either regular expressions to test the char or use the IndexOf function to search for the char in a string of known hexadecimal letters:
private void textBox2_TextChanged(object sender, EventArgs e) {
try {
textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
} catch {
}
}
Let us say you want to do one of 3 different actions depending on a value that will be the range of 1 to 24. I would suggest using a set of IF statements. And if that became too complex (Or the numbers were larger such as 5 different actions depending on a value in the range of 1 to 90) then use an enum to define the actions and create an array map of the enums. The value would then be used to index into the array map and get the enum of the action you want. Then use either a small set of IF statements or a very simple switch statement to process the resulting enum value.
Also, the nice thing about an array map that converts a range of values into actions is that it can be easily changed by code. With hard wired code you can't easily change behaviour at runtime but with an array map it is easy.
A more beautiful way to handle that
if ([4, 5, 6, 7].indexOf(value) > -1)
//Do something
You can do that for multiple values with the same result
Just to add to the conversation, using .NET 4.6.2 I was also able to do the following.
I tested the code and it did work for me.
You can also do multiple "OR" statements, like below:
switch (value)
{
case string a when a.Contains("text1"):
// Do Something
break;
case string b when b.Contains("text3") || b.Contains("text4") || b.Contains("text5"):
// Do Something else
break;
default:
// Or do this by default
break;
}
You can also check if it matches a value in an array:
string[] statuses = { "text3", "text4", "text5"};
switch (value)
{
case string a when a.Contains("text1"):
// Do Something
break;
case string b when statuses.Contains(value):
// Do Something else
break;
default:
// Or do this by default
break;
}
We can also use this approach to achieve Multiple cases in switch statement... You can use as many conditions as you want using this approach..
int i = 209;
int a = 0;
switch (a = (i>=1 && i<=100) ? 1 : a){
case 1:
System.out.println ("The Number is Between 1 to 100 ==> " + i);
break;
default:
switch (a = (i>100 && i<=200) ? 2 : a) {
case 2:
System.out.println("This Number is Between 101 to 200 ==> " + i);
break;
default:
switch (a = (i>200 && i<=300) ? 3 : a) {
case 3:
System.out.println("This Number is Between 201 to 300 ==> " + i);
break;
default:
// You can make as many conditions as you want;
break;
}
}
}
Using new version of C# I have done in this way
public string GetValue(string name)
{
return name switch
{
var x when name is "test1" || name is "test2" => "finch",
"test2" => somevalue,
_ => name
};
}
For this, you would use a goto statement. Such as:
switch(value){
case 1:
goto case 3;
case 2:
goto case 3;
case 3:
DoCase123();
//This would work too, but I'm not sure if it's slower
case 4:
goto case 5;
case 5:
goto case 6;
case 6:
goto case 7;
case 7:
DoCase4567();
}

Categories