How to make switch case syntax smaller? [closed] - c#

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];
}

Related

c# if statement, switch statement [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 3 years ago.
Improve this question
Let's make it easier. In this case return at the end have squigglies. What should I type in the return at the end to receive VK_F2 as a return value from the method?
internal uint AssignStartShortcut()
{
switch (currentStartValue)
{
case "F2":
return VK_F2;
}
return;// how this should look?
}
If I don't use return after swith then I have message: not all code paths return value.
Your error most likely is:
Compiler Error CS0165
Use of unassigned local variable 'name'
The C# compiler does not allow the use of uninitialized variables. If
the compiler detects the use of a variable that might not have been
initialized, it generates compiler error CS0165. For more information,
see Fields. Note that this error is generated when the compiler
encounters a construct that might result in the use of an unassigned
variable, even if your particular code does not. This avoids the
necessity of overly-complex rules for definite assignment.
Easy fix, initialize it:
internal uint AssignStopShortcut()
{
uint stopNumber = 0;
switch (currentStartValue)
...
Or make sure the static analyser knows that it can't fall through (i.e it is always initialized)
uint stopNumber;
switch (currentStartValue)
{
case "F3":
stopNumber = VK_F3;
return stopNumber; //squigly lines below
default:
// no other options
throw new InvalidOperationException("Bazzinga!");
}
Or even better, just return the constant, don't use the local variable.
internal uint AssignStopShortcut()
{
switch (currentStartValue)
{
case "F3":
return VK_F3; //squigly lines below
default:
throw new InvalidOperationException("Bazzinga!");
}
}
Adding to the TheGeneral's solution, your problem is that you need to initialise the variable.
internal uint AssignStartShortcut()
{
uint startNumber = 0; //initialise variable
if (currentStartValue == "F2")
{
startNumber = VK_F2;
}
return startNumber; //value of 0 is returned if the IF statement conditon is not met.
}
From your comment to TheGenral's proposed solution as I cannot yet make comments, is that since the initialised variable is set to Zero in this case and you are only doing a check for a particular value and if that condition is not met then "startNumber" won't be updated with "VK_F2" or "VK_F3" values. Therefore, that's why the Switch statement default case is met as the "currentStartValue" had not met any of the cases.
For example if you wanted to check for all cases, it should look something like this:
internal uint AssignStopShortcut()
{
uint stopNumber = 0; //initialise this variable is a must if it's to be declared in this method.
switch (currentStartValue)
{
case "F1": break;
case "F2": break;
case "F3":
stopNumber = VK_F3;
break;
case "F4": break;
case "F5": break;
case "F6": break;
case "F7": break;
case "F8": break;
default:
// no other options
throw new InvalidOperationException("Bazzinga!");
}
return stopNumber;
}
Hope this helps.
Thanks to all of you guys for your help. Problem solved and it wasn't in if or switch statement. Turns out data that should be passed simply wasn't. My bad. Thanks again.

How should I convert enum type to string in C# [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 5 years ago.
Improve this question
I have an enum inside a class called cConstsAndEnums:
public class cConstsAndEnums
{
public enum EnSelectedKtovet
{
En_KtovetMaam = 1,
En_KtovetTmg
};
}
In other class I have switch:
switch (dr["rowSelectedKtovet"].ToString())
{
case cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam:
doSomthing;
break;
default:
}
The problem is that I'm getting an error:
Cannot implicitly convert type 'cConstsAndEnums.EnSelectedKtovet' to 'string'.
I try to do:
case (string)cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam:
but I have error:
Cannot convert type 'cConstsAndEnums.EnSelectedKtovet' to 'string'.
Tried also:
case Convert.ToString(cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam):
but again I have error:
A constant value is expected.
Please help.
Thanks.
The reason is the data type of the switch (string) is different to your cases (enum values). Trying to solve this by using .ToString() means you are doing an operation, but a case needs always a constant value. Do it the other way and cast the string to the enum before using it at the switch.
cConstsAndEnums.EnSelectedKtovet enumValue = (cConstsAndEnums.EnSelectedKtovet)
Enum.Parse(typeof(cConstsAndEnums.EnSelectedKtovet, dr["rowSelectedKtovet"].ToString());
switch (enumValue)
{
case cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam:
...
}
Also think about to store the numeric value of the enumeration instead of the string value. Every enum literal has a value which you can simply cast to an integer:
EnSelectedKtovet enumValue = EnSelectedKtovet.En_KtovetMaam;
int storedEnumValue = (int)enumValue;
EnSelectedKtovet restoredEnumValue = (EnSelectedKtovet)storedEnumValue;
With this solution you dont need to deal with any string, which is much more safe and comfortable.
You should use Enum.Parse() method (in case if you ensure that string has always prvoded enum value) or Enum.TryParse() (in case if string cuold have anything, so you can set your enum to default value)
In your case try this:
var myEnum = (EnSelectedKtovet)Enum.Parse(typeof(EnSelectedKtovet), dr["rowSelectedKtovet"].ToString());
switch (myEnum)
{
case EnSelectedKtovet.En_KtovetMaam:
doSomthing;
break;
default:
}
In your switch statement, convert it to the enum
switch(Enum.Parse(typeof(EnSelectedKtovet), dr["rowSelectedKtovet"].ToString()){
case cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam:
doSomthing;
break;
default:
}
switch ((EnSelectedKtovet)int.Parse(dr["rowSelectedKtovet"].ToString()))
{
case EnSelectedKtovet.En_KtovetMaam:
break;
default:
break;
}
I hope it will work for you.
This is a case of the XY Problem. You are asking about your attempted solution, not the actual problem.
In this case the actual problem is that you read an enum value from the database. The index method returns an object so you can't compare it with anything else directly. You'd have to cast it to an int (if the database returns an int) or a string. You can cast it to an enum directly too, since enums are basically named integers.
Instead of that, you tried to convert it to a string. When you tried to compare that string to the enum values, you got a compilation error because obviously an enum isn't a string.
If the underlying field value is an integer, you can just cast it to the enum's type:
var value=(cConstsAndEnums.EnSelectedKtovet)dr["rowSelectedKtovet"];
switch (value)
{
case cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam:
doSomthing;
break;
default:
}
If it's a string that contains the enum name, you'll have to parse the string with Enum.Parse or Enum.TryParse
var fieldValue=(string)dr["rowSelectedKtovet"];
var value=Enum.Parse(typeof(cConstsAndEnums.EnSelectedKtovet),fieldValue);
switch (value)
...
With a bit of C# 7 and pattern matching magic, you could match both cases:
var value=dr["rowSelectedKtovet"];
switch(value)
{
case int val when Enum.IsDefined(typeof(cConstsAndEnums.EnSelectedKtovet),val) :
var enumValue=(cConstsAndEnums.EnSelectedKtovet)val;
//Use enumValue
break;
case string s when Enum.TryParse<cConstsAndEnums.EnSelectedKtovet>(s,out var enumValue):
//Use enumValue
break;
default :
throw new ArgumentException($"Unknown {value}");
}
You Can try.ToString("D") to compare with Enum value.
string selectedValue= dr["rowSelectedKtovet"].ToString();
if(selectedValue==cConstsAndEnums.EnSelectedKtovet.En_KtovetMaam.ToString("D"))
{
doSomthing();
}

Switch statement with multiple conditions on C# [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 7 years ago.
Improve this question
Could you tell me how to use switch with the below mentioned code snippet ?
if (IsSelectedOrganizer)
{
//
}
else if (IsNewOrganizer && IsOrganizerUserAlreadyExist)
{
//
}
else if (IsNewOrganizer && !IsOrganizerUserAlreadyExist)
{
//
}
else
{
//
}
But on Javascript we can do that as shown below.But C# it doesn't allow ? It says A constant value is expected
switch (true) {
case IsSelectedOrganizer:
//
break;
case IsNewOrganizer && IsOrganizerUserAlreadyExist:
//
break;
case IsNewOrganizer && !IsOrganizerUserAlreadyExist:
//
break;
}
That's a perfect use case for an if not for a switch, so i suggest to keep it. But you could improve it a little bit:
if (IsSelectedOrganizer)
{
//
}
else if (IsNewOrganizer)
{
if (IsOrganizerUserAlreadyExist)
{
//
}
else
{
//
}
}
else
{
//
}
A switch statement cannot have multiple conditions in it like if/else does, this is because switch is typically implemented as a fast in-program hashtable which means that: 1) All comparison values must be const, and 2) it doesn't actually perform as many comparisons as there are switch case expressions.
There is a "workaround" that requires converting a boolean expression into a custom enum value and then switching on that, but I don't see how it would be of any help in this situation.
That's not a great candidate for a switch statement as your logic depends on the values of several variable rather than checking a single variable for different values.
Here's an example of the sort of code that's easy to convert to a switch statement:
if (value == 0)
{
// do stuff
}
else if (value == 1)
{
// etc
}
As a switch statement that would be:
switch (value)
{
case 0:
// do stuff
break;
case 1:
// etc
break;
}
There's nothing wrong with using if...else if statements if you're checking combinations of different variables, as you are. If for some reason you have to use a switch statement, the best solution would be to create an enum with values representing each of your possible states, then switch on that. For example:
enum OrganizerType
{
SelectedOrganizer,
NewOrganizerUserExists,
NewOrganizerUserDoesntExist
}
// ...
OrganizerType orgType = calculateOrgType();
switch (orgType)
{
case SelectedOrganizer:
// do stuff
break;
// etc
}
As an exercise purely is "can it be done?", here's a solution. No developer, ever, should consider using this in real life though:
var switchValue = IsSelectedOrganizer ? 4 : 0 +
IsNewOrganizer ? 2 : 0 +
IsOrganizerUserAlreadyExist ? 1 : 0;
switch (switchValue)
{
case 7:
case 6:
case 5:
case 4:
// IsSelectedOrganizer part
break;
case 3:
// IsNewOrganizer && IsOrganizerUserAlreadyExist part
break;
case 2:
// IsNewOrganizer && !IsOrganizerUserAlreadyExist part
break;
default:
// else part
}
public int FlagValues
{
return (IsSelectedOrganizer & 1) + (IsNewOrganizer & 2) + (IsOrganizerUserAlreadyExists & 4)
}
switch (FlagValues)
In no respect better than using ifs but implemented using switchs ;-).
switch (IsSelectedOrganizer)
{
case true:
{
//
}
break;
default:
{
switch (IsNewOrganizer)
{
case true:
{
switch ((IsOrganizerUserAlreadyExist))
{
case true:
{
//
}
break;
default:
{
//
}
break;
}
}
break;
default:
{
//
}
break;
}
}
break;
}

How to handle multiple values inside one case? [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 8 years ago.
Improve this question
How to handle multiple values inside one case? So if I want to execute the same action for value "first option" and "second option"?
Is this the right way?
switch(text)
{
case "first option":
{
}
case "second option":
{
string a="first or Second";
break;
}
}
It's called 'multiple labels' in the documentation, which can be found in the C# documentation on MSDN.
A switch statement can include any number of switch sections, and each section can have one or more case labels (as shown in the string case labels example below). However, no two case labels may contain the same constant value.
Your altered code:
string a = null;
switch(text)
{
case "first option":
case "second option":
{
a = "first or Second";
break;
}
}
Note that I pulled the string a out since else your a will only be available inside the switch.
It is possible
switch(i)
{
case 4:
case 5:
case 6:
{
//do someting
break;
}
}
You may be better off using just an if statement if you want to be able to treat both together and separate as distinct cases:
if (first && second)
{
Console.WriteLine("first and second");
}
else if (first)
{
Console.WriteLine("first only");
}
else if (second)
{
Console.WriteLine("second only");
}

Clear way to write if statement [closed]

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.

Categories