I am convertng vb.net to c# 2010 as my job, and none of the automatic tools I have can succeed completely. In special example, this case:
'searchString is a string paramter from a long method
Select Case searchString
Case "paid"
'Do something long here
Case "oaaaaa" To "ozzzzzz", "maaaaaa" To "mzzzzzz"
'Do other long code
Case Else
'other long code
End Select
I am mostly java developer before this, so not great with c# and none with vb.net. I do not understand the "oaaaa to ...." part and this part is not converting. Can you please point me to right place to find the c# version of this?
There isn't a direct equivalent in C# but you can easily achieve the same semantics (with more readable code!) using the following:
if(searchString == "paid") {
// do something here
}
else if(
searchString.IsInRange("oaaaaa", "ozzzzzz") ||
searchString.IsInRange("maaaaa", "mzzzzzz")
) {
// do other long code
}
else {
// other long code
}
public static class StringExtensions {
public static bool IsInRange(this string s, string lower, string upper) {
if(String.Compare(lower, upper) > 0) {
throw new InvalidOperationException();
}
return String.Compare(s, lower) >= 0 && String.Compare(s, upper) <= 0
}
There's no direct C# equivalent of the Case "xxx" To "yyy" syntax. I suppose the closest translation will probably be an if/else if/else stack:
if (seachString == "paid")
{
// do something long here
}
else if (((searchString.CompareTo("oaaaaaa") >= 0) && (searchString.CompareTo("ozzzzzz") <= 0))
|| ((searchString.CompareTo("maaaaaa") >= 0) && (searchString.CompareTo("mzzzzzz") <= 0)))
{
// do other long code
}
else
{
// other long code
}
C# doesn't seem to have the concept of Case ... To. See http://msdn.microsoft.com/en-us/library/cy37t14y(VS.80).aspx. The C# example says "This language is not supported".
bitwise has the answer, but here is the translated code (it's just like javascript):
switch (searchString){
case: "paid"
'Do something long here
break;
case: "oaaaaa" To "ozzzzzz", "maaaaaa" To "mzzzzzz"
'Do other long code
break;
default:
'other long code
break;
}
Related
if(i<2 && i>10){
//code here will never be reached or what?
}
Just in case of an integer overflow maybe?
Edit: I wrote this not knowing c# is the language used. I've used C++ but I believe that the principle is also valid for c#.
there is no single integer that satisfies the condition
the compiler may well optimize away the body of the if condition (see here for an example on compiler explorer)
however, in the case of i being volatile it is possible that the value of i changes between the i<2 and the i>10 tests. In this case the if body can be reached.
However, though it may be theoretically possible it is highly unlikely that this was the intention.
Here's my example code
#include <iostream>
using std::cout;
void foo(int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in foo\n";
}
}
void bar(volatile int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in bar\n";
}
}
It is indeed possible for some c# (assuming c# because it's tagged... not assuming integer even if it's tagged because the right-hand comparison is still an integer, so it matches the tags! ;-) ) code to go into that if... take:
public class Foo {
public static bool operator> (Foo a, int b) {
return true;
}
public static bool operator< (Foo a, int b) {
return true;
}
}
Then:
Foo i = new Foo();
if(i<2 && i>10){
Console.WriteLine("Pass!");
}
Guess the output? Check it out here
Another way, with no extra classes or operator overloading:
private static bool odd;
public static int i { get { odd = !odd; return odd ? 1 : 11; } }
Check it out
Otherwise, it could also happen if multithreading (if the value of i changes bewtween the comparisons) unless you apply correct locking
How can I use && operator in switch case?
This is what i want to do:
private int retValue()
{
string x, y;
switch (x && y)
{
case "abc" && "1":
return 10;
break;
case "xyz" && "2":
return 20;
break;
}
}
My problem is that "abc" and "1" are both of type string and the compiler gives me message that:
"operator && cannot be applied to string"
There is no such operator in switch statements. The switch statement operates on a single variable which is a value type or a string. See:
http://www.dotnetperls.com/switch
http://msdn.microsoft.com/en-us/library/06tc147t.aspx
The real problem in your example is that both in the switch expression, and in case labels, you are applying && to strings. You cannot apply && to strings, it only works on booleans (unless you overload it and define a new function that does work on strings).
What you are trying to accomplish is probably to simultaneously check the values of two different variables with one switch. This is impossible; switch only checks one variable at a time. The solution is to use if statements or a specialized CheckStrings(string s1, string s2) method (which may or may not use if statements).
In a comment you have expressed concerns with length. Observe:
private int retValue(string x, string y)
{
if (x == "abc" && y == "1") return 10;
if (x == "xyz" && y == "2") return 20;
throw new Exception("No return value defined for these two strings.")
}
Shorter, even if you discount the gains from skipping redundant break; statements and putting returns on the same line.
Despite there is an accepted answer already...
To achieve logical AND in switch, it has to be done like this:
switch(x + y)
{
case "abc1":
return 10;
break;
case "xyz2":
return 20;
break;
}
Which works.
For logical OR see zey answer.
You mean like that ?
switch (value)
{
case "abc":
case "1":
return 10;
case "xyz":
case "2":
return 20;
}
If you are using C# 8 and above below code snippet will yield the desired result. This is using pattern matching with expression future.
string x = "abc", y = "2";
var result = (x, y) switch
{
("abc","1") => 10,
("xyz","2") => 20,
(_,_) => 0
};
Console.WriteLine($"Arguments : {x}, {y}, result : {result}");
switch statement can only be applied to integer values or constant expressions. If you want to check your conditions on string type variable, then you should use if-else-if structure.
This question already has answers here:
Control cannot fall through from one case label
(8 answers)
Closed 9 years ago.
I am trying to convert an if statement to switch cases (for readability)
1) I've read switch statements are aweful in general - Is that true?
https://stackoverflow.com/questions/6097513/switch-statement-inside-a-switch-statement-c
2) The statement goes like this:
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
case Display.NonExpense:
if (expected.EXPENSE == true)
break;
case Display.All:
//Code
break;
}
Error is:
Control cannot fall through from one case label ('case 1:') to another
This is the original if statement:
if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
First off, I notice that you forgot to ask a question in your second point. So I'm going to ask some questions for you addressing your second point:
What is the meaning of the "can't fall through" error?
Unlike C and C++, C# does not allow accidental fall-through from one switch section to another. Every switch section must have an "unreachable end point"; it should end with a break, goto, return, throw or (rarely) infinite loop.
This prevents the common bug of forgetting to put in the break and "falling through" accidentally.
You've written your code as though fall-through is legal; my guess is that you're a C programmer.
How can I force fall-through in C#?
Like this:
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
else
goto case Display.All;
case Display.NonExpense:
if (expected.EXPENSE == true)
break;
else
goto case Display.All;
case Display.All:
//Code
break;
}
Now the reachability analyzer can determine that no matter which branch of the "if" is taken, the switch section endpoint is unreachable.
Is this good style?
No. Your original code was a lot more readable.
I've read switch statements are aweful in general - Is that true?
Opinions vary. Switch statements are very useful when there is a small number of very "crisp" alternatives whose behaviours do not interact in complex ways. Some people will tell you that switched logic should instead be handled by virtual methods or visitor patterns, but that can be abused as well.
Should I use a switch in this particular case?
I wouldn't.
How would you improve my code?
if ((Show == Display.All) ||
(expected.EXPENSE == true && Show == Display.Expense) ||
(expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
First off, don't name things IN ALL CAPS in C#.
Second, don't compare Booleans to true and false. They're already Booleans! If you want to know the truth of statement X you would not say in English "is it true that X is true?" You would say "Is X true?"
I would likely write:
if (Show == Display.All ||
Show == Display.Expense && expected.Expense ||
Show == Display.NonExpense && !expected.Expense)
{
//Code
}
Or, even better, I would abstract the test away into a method of its own:
if (canDisplayExpenses())
{
//Code
}
Or abstract the whole thing away:
DisplayExpenses();
The compiler will not understand what you mean here.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
// missing break here
case Display.NonExpense:
The compiler will not connect the dots and understand that the break; statement inside your if statement is linked to the switch statement. Instead it will try to link it to a loop, since break; statements on their own can only be used with loops, to break out of it.
That means that your case block is missing its break statement to complete it, and thus the compiler complains.
Instead of trying to wring the necessary code out of a switch statement, I would instead break up your original if statement.
This is yours:
if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
This is how I would write it:
bool doDisplayExpected =
(Show == Display.All)
|| (Show == Display.Expense && expected.EXPENSE)
|| (Show == Display.NonExpense && !expected.EXPENSE);
if (doDisplayExpected)
{
// code
}
You don't have to pack everything on one line.
Also, I would try to name properties so that they're easier to read, I would rename the EXPENSE property to IsExpense so that the above code would read like this:
bool doDisplayExpected =
(Show == Display.All)
|| (Show == Display.Expense && expected.IsExpense)
|| (Show == Display.NonExpense && !expected.IsExpense);
if (doDisplayExpected)
{
// code
}
Then, ideally, I would refactor out the sub-expressions to methods:
bool doDisplayExpected =
ShowAll()
|| ShowExpense(expected)
|| ShowNonExpense(expected);
if (doDisplayExpected)
{
// code
}
public bool ShowAll()
{
return Show == Display.All;
}
public bool ShowExpense(Expected expected)
{
return Show == Display.Expense && expected.EXPENSE;
}
public bool ShowNonExpense(Expected expected)
{
return Show == Display.NonExpense && !expected.EXPENSE;
}
Then you can put the expression back into the if-statement:
if (ShowAll() || ShowExpense(expected) || ShowNonExpense(expected))
{
// code
}
This should be easier to read, and change later on.
Use if statements and extract complex conditions into methods, e.g
if (ShowAll() || ShowExpense())
{
}
Remember about OOP and polymorphism every time you write such 'switch', adding another
case to that code will be a nightmare
see this and similar (C++) instructions about converting switches
P.S if you are interested in making your code clean and readable, consider reading Smalltalk Best Practice Patterns by Kent Beck and/or Clean Code by Uncle Bob
I really enjoyed both of them, highly recommend.
If you want readability, just throw away your syntax trash:
if (Show == Display.All || expected.EXPENSE && Show == Display.Expense || !expected.EXPENSE && Show == Display.NonExpense)
{
//Code
}
Provide the else part for each of them so it will not throw error, however as others say, you actually don't need switch in this case.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
// do what you want
break;
else
// do what you want
break;
case Display.NonExpense:
if (expected.EXPENSE == true)
// do what you want
break;
else
// do what you want
break;
case Display.All:
//Code
break;
}
The reason why you get this error is that you are not defining break statements.
You defined the break conditionally.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
// Note that the break above is in scope of you if statement, and will
// result in a compiler error
case Display.NonExpense:
...
}
Either make sure every case statement has its own break or group the case statements as follows.
switch (Show)
{
case Display.Expense:
case Display.All:
// do stuff
// Expense and All have the same behavior
}
Refactor out the if statements so you can express it like so:
if (isDisplayAll() || isExpense(expected) || isNonExpense(expected))
{
// Code
}
The extracted logic:
private bool isDisplayAll()
{
return (Show == Display.All);
}
private bool IsExpense(Expected expected)
{
return expected.EXPENSE && (Show == Display.Expense);
}
private bool IsNonExpense(Expected expected)
{
return !expected.EXPENSE && (Show == Display.NonExpense);
}
Agree with Dennis, you don't want a switch case for this problem.
Although probably less readable, you can also use shorter:
if (Show == Display.All || (expected.EXPENSE == (Show == Display.Expense)))
{
//Code
}
How can I test if value of int is for example 1,2,4 or 5? I thought i could do something like this but apparently not.
if(someInt == (1||2||4||5))
Use LINQ:
if ((new[] {1,2,4,5}).Contains(someInt))
Write an extension method
static class MiscExtensions
{
static bool EqualToAny<T>(this T i, params T[] items)
{
return items.Any(x => x.Equals(i));
}
}
And use it like so
static class Program
{
static void Main(string[] args)
{
int myNumber = 5;
if (myNumber.EqualToAny(1, 2, 3, 4, 5))
Console.WriteLine("Hello, World");
}
}
As an alternative you can use:
switch(someInt)
{
case 1:
case 2:
case 4:
case 5:
DoYourStuff();
break;
}
There are two ways I can think of.
Or all the comparisons.
if (someInt == 1 || someInt == 2 || someInt == 4 || someInt == 5) {
}
Or for a more flexible solution see if someInt is in an array.
if (Array.BinarySearch(new[] { 1, 2, 4, 5 }, someInt ) != -1) {
}
You need to write your if statement like this
if (someInt==1 || someInt==2 || someInt==4 || someInt==4)
Or you could use a switch statement
switch (someInt)
{
case 1:
case 2:
case 4:
case 5:
// do something
break;
}
Breaking down your attempted code is quite interesting. You wrote:
if(someInt == (1||2||4||5))
I guess in your head you read it as, if someInt equals 1 or 2 or 4 or 5. And if computers behaved like humans then this would work. But we all know that computers don't behave like that!
The == equality operator, a binary operator, returns true when its two operands are equal. So that means, in your version, if it compiled, you would need someInt to be equal to (1||2||4||5). And for that to even be meaningful, we would need (1||2||4||5) to evaluate to a single value, instead of producing a compile error. And, if it did evaluate to a single value, then it could not have the meaning which you want. Because you want the test to return true when someInt is equal to one of four candidate values.
The bottom line is that == tests for exact equality between precisely two values.
You can't do it like that. Instead use:
if(someInt == 1 || someInt == 2 || someInt == 4 || someInt == 5)
Or also you could use something like this:
if((new List<int>() {1,2,4,5}).Contains(someInt) == true)
I'm dealing with a program that does plenty of if...else branching based on command line arguments. This is in C# but I'm sure it's applicable to Java, C++ etc. Here's the general outline:
if (args.Length == 0)
{
//do something
}
if (args.Length > 0 && args.Length < 2)
{
Console.WriteLine("Only one argument specified. Need two arguments");
return 0;
}
else if (args.Length > 0 && args.Length >= 2)
{
//Process file - Argument 1
if(args[0].Trim() == PROCESS_OPTION_ONE
|| args[0].Trim() == PROCESS_OPTION_TWO)
{
//Process file - Argument 2
if(args[1].Trim() == PROCESS_CUSTOMER
|| args[1].Trim() == PROCESS_ADMIN
|| args[1].Trim() == PROCESS_MEMBER
|| args[1].Trim() == PROCESS_GUEST
|| args[1].Trim() == PROCESS_USER
)
{
So as you can tell, it's kind of a mess. Is there a design pattern or two that would be most applicable toward cleaning things up some? Command pattern, perhaps? Thanks for the advice and tips.
Stop nesting.
You can switch like (+1) Joel said, or you can just break your logic into clear method calls.
if(args.Length <= 1)
{
Console.WriteLine("Need 2 args kthx");
return;
}
if(args.Length > 2)
{
Console.WriteLine("More than 2 args don't know what do");
return;
}
var arg1 = args[0].Trim();
var arg2 = args[1].Trim();
switch(arg1)
{
case PROCESS_OPTION_ONE:
ProcessOptionOne(arg2);
break;
case PROCESS_OPTION_TWO:
ProcessOptionTwo(arg2);
break;
default:
Console.WriteLine("First arg unknown I give up");
return;
}
then, in your process methods...
private static void ProcessOptionTwo(string argumentTwo)
{
if(argumentTwo == PROCESS_CUSTOMER ||
argumentTwo == PROCESS_ADMIN ||
/* etc blah blah */
}
Keep your methods as simple as possible and break up longer, confusing algorithms into distinct method calls which, through their name, give a clear indication of what they are doing.
I'm partial to using switch statements on the arguments array and setting properties in a configuration class of some kind for each anticipated argument. It appears you're expecting a very specifically formatted argument string rather than allowing set values, you could try:
if(args[0].Trim() == PROCESS_OPTION_ONE || args[0].Trim() == PROCESS_OPTION_TWO)
{
//Process file - Argument 2
switch(args[1].Trim()
{
case PROCESS_CUSTOMER, PROCESS_ADMIN, PROCESS_MEMBER, PROCESS_GUEST, PROCESS_USER:
// Do stuff
break;
default:
// Do other stuff
break;
}
}
My preferred method would be something like
foreach(string arg in args)
{
switch(arg)
{
case PROCESS_CUSTOMER:
// Set property
break;
...
default:
// Exception?
break;
}
}
NOTE: args.Length == 1 is faster than args.Length > 0 && args.Length < 2. It's also a little more readable.
You don't need the else if you've already returned. That might cut out a lot of your nesting. You could also try using a switch instead of a bunch of nested ifs.
I took the code from this Code Project article a long time ago and made my own version of it to use for command line applications. I did my own modifications to it, like making the class inherit from Dictionary, etc. But the regex part of the code is very good, and makes these sort of command line switches easy as pie.