I have written a piece of lousy code in C#.NET and i want to optimize it.
All i can think of at the moment is to separate the common portions into a separate method.
Code :
if(condition1)
{
switch(condition)
case 'A' : //Some code
break;
case 'B' : //Some code
break;
case 'C' : //Some code
break;
}
else if(condition2)
{
switch(condition)
case 'a' : //Some code
break;
case 'B' : //Some code
break;
case 'C' : //Some code
break;
}
Note that the case statements conditions for case 'B' and case 'C' are common.
Any help on improving the code is deeply appreciated.
Why don't you stack the case statements if their code block should do same code
Like this
case 'B' :
case 'C' :
{
//Do Some Code
}
break;
case "a":
case "A":
if ( condition1) {
...
}
else if { condition2}
...
}
break;
All you can do is putting the common code together and check the additional condition there.
switch(condition)
{
case 'A':
if(condition1) //do something
else //do something
break;
case 'a':
same as above
case 'B':
break;
case 'C':
break;
}
I think even if you optimize that piece of code, it would still be very fragile and hard to maintain. I would suggest to try to refactor it using strategy-pattern for example (if it's possible of course).
You would benefit a lot, cause you isolate each routine and do it OOP-way, making it easier to change and maintain in future.
Related
I'm trying to learn programming C# (self taught) and I came to a point where I don't know if switch case can be used like if condition.
Can I make a comparison with switch like this?
switch(var)
{
case var < 10:
//Do something
break;
}
Or this is a case of why if condition is different compared to switch?
Certain comparisons can be done in switch cases via patterns. In your specific scenario, a relational pattern could check if a switch input is < 10.
switch(var)
{
case < 10:
//Do something
break;
}
One significant limitation of patterns is that the values inside them have to be constant. So if you had a variable int x and tried to use it in case < x: it wouldn't work.
https://dotnetcoretutorials.com/2020/08/10/relational-pattern-matching-in-c-9/
Deciding if to use an IF statement or SWITCH statement depends on a number of factors, including the readability of your code. There are times when multiple IF statements provide a more simpler approach than using switch. Other times it would be best to use a switch statement.
The simple answer to your question is yes but it would be best for you to try both in a particular scenario if you want to learn.
For most purposes switch is an alternative way to write an chain of if/else statement
switch(myVar)
{
case 1:
//Do something
break;
case 2:
//Do something
break;
case 3:
//Do something
break;
default:
//Do something else
}
Is equivalent to
if(myVar == 1) {
//Do something
}
else if(myVar == 2) {
//Do something
}
else if(myVar == 3) {
//Do something
}
else {
//Do something
}
In older versions of C# (pre 7.0) case statements were restricted to only testing if values were equal to a constant. However with the introduction of a feature called 'pattern matching' you can do more expressive matches within case statements. Subsequent C# versions have added more and more syntax in this area, but ultimately they don't do anything beyond what can be achieved with an if/else chain. For situations where there are a lot of conditions the switch/case statements are typically easier to read
An example of changes in syntax being allowed C# 9.0
switch(myVar)
{
case == 1:
//Do something
break;
case > 1 and < 3:
//Do something
break;
case == 3:
//Do something
break;
default:
//Do something else
}
Usually I will implement switch case in a method that return particular object. Something like below:
private string testing(string input){
switch(input)
{
case "a":
{
....
return "TestingResult";
}
case "b":
{
....
return "TestingResultB";
}
default:
return null;
}
}
Now I'm wondering if it's possible to write a switch case for value assignment purpose? Something like below:
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
{
....
TEST = "TestingResult";
}
case "b":
{
....
TEST = "TestingResultB";
}
default:
}
return TEST;
}
Of cause it can be achieve by simple If-Else statement, this question is for me to understand more functionality of switch case
Of course, after testing it, I receive error
control cannot fall through from one case label('case: "a"') to another
You need to add break; in each case
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
TEST = "TestingResult";
break;
case "b":
TEST = "TestingResultB";
break;
default:
}
return TEST;
}
As others have mentioned, the braces within each case are unnecessary.
Yes you can. You just have to remember to put a 'jump' statement of some kind (this includes break, goto case, return, or throw), after each case label:
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
TEST = "TestingResult";
break;
case "b":
TEST = "TestingResultB";
break;
}
return TEST;
}
Note, the braces here are unnecessary, and the default isn't required in this construction as it will fall through the switch block if it doesn't match any of the cases.
Further Reading
switch (C# Reference)
What you've written is perfectly legitimate, however there is no point doing the value assignment unless you are going to carry on and do some further operations with it before returning.
To help you with becoming more proficient with switch/case statements:
in your first example you don't need the default, just have a final return at the end of the function
in your second example, you don't need the default at all - you do nothing with it
a switch/case is usually used for multiple options, for example 4 or more. Any less than that and an if/else is equally readable. You should also bear in mind that a switch/case can give you good speed improvements in some cases
This question already has answers here:
Is there a better alternative than this to 'switch on type'?
(31 answers)
C# switch on type [duplicate]
(5 answers)
Closed 9 years ago.
I understand that C# compiler as it stands does not let switching on Type like
switch (typeof(MyObj))
case Type1:
case Type2:
case Type3:
There are solutions where a Dictionary of Type and Action could be used or a static class (link), but I am just curious, why is this a bad practice or not implemented in the compiler yet ?
Thank you in advance.
If you're talking about primitive types you can do switch over TypeCode.
var typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Empty:
break;
case TypeCode.Object:
break;
case TypeCode.DBNull:
break;
case TypeCode.Boolean:
break;
case TypeCode.Char:
break;
case TypeCode.SByte:
break;
case TypeCode.Byte:
break;
case TypeCode.Int16:
break;
case TypeCode.UInt16:
break;
case TypeCode.Int32:
break;
case TypeCode.UInt32:
break;
case TypeCode.Int64:
break;
case TypeCode.UInt64:
break;
case TypeCode.Single:
break;
case TypeCode.Double:
break;
case TypeCode.Decimal:
break;
case TypeCode.DateTime:
break;
case TypeCode.String:
break;
}
BTW answer for your question you may need to read How many Microsoft employees does it take to change a lightbulb?
I would refer you to the accepted answer for : switch statement in C# and "a constant value is expected" . The compiler needs to know at compile time that there won't be any duplicates, so it accepts only constants. By the way, you can achieve the same effect with
switch (typeof(MyObj).FullName
and use the names of each type as case conditions, like:
case "MyNamespace.Type1":
/*stuff*/
break;
case "MyNamespace.Type2":
/*other stuff*/
break;
default:
/*default stuff*/
When would you use switching on type? Most of the cases I can think of are better solved with inheritance, i.e. rather than doing:
switch (typeof(MyObj)) {
case Type1: doSomethingForType1; break;
case Type2: doSomethingForType2; break;
case Type3: doSomethingForType3; break;
You would set it up in a much more object-oriented manner:
Interface ISpecialType {
void doSomething();
}
Type1 : ISpecialType {
doSomething() {}
}
Type2 : ISpecialType {
doSomething() {}
}
Type3 : ISpecialType {
doSomething() {}
}
then, no matter what, you just call MyObj.doSomething(); It's a little bit more typing at the start, but a lot more robust.
Also, if it's really important to you to switch on, you can always use typeof(MyObj).toString() and switch on that. It's not recommended practice, since you're then hard-coding strings that are allowed to change into your switch, but you can do it.
I have a switch statement:
swtich(x)
{
case 1:
...
break;
case 2:
...
break;
}
I want to put the ... code in a function but I want to put the break too... So I want something like that
void func()
{
...;
break;
}
swtich(x)
{
case 1:
func();
case 2:
func();
}
Break gives error (I know why) but what I can do?
You can't. Best you can do is:
swtich(x)
{
case 1:
func();
break;
case 2:
func();
break;
}
See here for a discussion of what break is for:
The break statement terminates the closest enclosing loop or switch statement in which it appears. Control is passed to the statement that follows the terminated statement, if any.
If you put it in a function, how will it know which loop or switch statement it's supposed to apply to?
You can't put the break in another method.
Though if you want case 1 and case 2 to do the same thing, this is legal:
switch (x)
{
case 1:
case 2:
func();
break;
}
As others have said, it's not possible. Look at it this way, what would be the expected behavior be if you were not inside a switch statement when the execution gets to the break; line?
Put the break; statement after the function call. If you want the function to stop execution under a given condition, use the return; statement.
Don't put the break in the function. Plain and simple.
switch(x)
{
case 1:
func();
break;
case 2:
func();
break;
}
I have two questions with this code:
public int InsertOrUpdateRecord(char _code, string _databaseFileName)
{
switch(_code)
{
case 'N':
// Some code here
case 'U':
// Some code here
}
return 0;
}
It is not accepting char single quote and double quote value.
If I pass _code as string, it gives red underline in case with this error:
Control cannot fall through one case label to another.
The reason for the compilation error is that the case is missing the break
switch (_code)
{
case 'N':
// Some code here
break; // break that closes the case
case 'U':
// Some code here
break; // break that closes the case
}
You need to do a break at the end of the case:
switch (_code)
{
case 'N':
// Some code here
Console.WriteLine("N was passed");
break;
case 'U':
// Some code here
Console.WriteLine("U was passed");
break;
}
Unless you want in either cases to do the same like so:
switch(_char) {
case 'N':
case 'U':
// Common code for cases N and U here...
}
You have to specifically tell the compiler where the case statement halts:
switch(_char) {
case 'N':
// Code here...
break; // The N case ends here.
case 'U':
// Code here with different behaviour than N case...
break; // The U case ends here.
}
The break statement tells the compiler that you're done with that case, and that it has to get out of the switch instruction.
you can either write a break or return statement like the below code.
char _code = 'U';
switch (_code)
{
case 'N':
case 'U':
return;
}
OR,
char _code = 'u';
switch (_code)
{
case 'N':
case 'U':
break;
}
There is no problem with char. See this msdn article about your error.