Okay, if I have a string that I want to be equal to something based on multiple conditions, what's the best way to implement that?
Psuedocode
int temp = (either 1, 2, or 3)
string test = (if temp = 1, then "yes") (if temp = 2, then "no") (if temp = 3, then "maybe")
Is there some concise way to do this? What would you do?
Use a switch
switch(temp)
{
case 1:
return "yes";
case 2:
return "no";
case default:
return "maybe";
}
You can use a switch statement as mentioned in other answers but a dictionary can also be used:
var dictionary = new Dictionary<int, string>();
dictionary.Add(1, "yes");
dictionary.Add(2, "no");
dictionary.Add(3, "maybe");
var test = dictionairy[value];
This method is way more flexible than a switch statement and ever more readable than nested tenary operator statements.
string test = GetValue(temp);
public string GetValue(int temp)
{
switch(temp)
{
case 1:
return "yes";
case 2:
return "no";
case 3:
return "maybe";
default:
throw new ArgumentException("An unrecognized temp value was encountered", "temp");
}
}
You can use a switch statement
string temp = string.Empty;
switch(value)
{
case 1:
temp = "yes";
break;
case 2:
temp = "no";
break;
case 3:
temp = "maybe";
break;
}
The basic idea is:
String choices[] = {"yes","no","maybe"};
string test = choices[temp-1];
There are many different ways of actually implementing it. Depending on what your condition variable is, you might like to implement it as some sort of key-value list. SEE Zeebonk's answer for an example.
the obvious answer would be switch case
but just another flavor:
int temp = x; //either 1,2 or 3
string test = (temp == 1 ? "yes" : temp == 2 ? "no" : "maybe");
This switch is closer to your pseudocode and is exact C# code:
int temp = /* 1, 2, or 3 */;
string test;
switch(temp)
{
case 1:
test = "yes";
break;
case 2:
test = "no";
break;
case 3:
test = "maybe";
break;
default:
test = /* whatever you want as your default, if anything */;
break;
}
Your pseudocode doesn't include a default case, but it's good practice to include one.
The most concise answer is the nested ternary operator
string test = (temp == 1 ? "yes" : (temp == 2 ? "no" : (temp == 3 ? "maybe" : "")));
if temp values are only 1,2,3 then
string test = (temp == 1 ? "yes" : (temp == 2 ? "no" : "maybe"));
of course this is the concise answer as asked, and this doesn't means that it is the best.
If you could not exclude that, in future you will need more values to test, then it is better to use a dictionary approach as explained in the #zeebonk answer.
You can also turn things around:
class Program
{
enum MyEnum
{
Yes = 1,
No,
Maybe
}
static void Main(string[] args)
{
Console.WriteLine(MyEnum.Maybe.ToString());
Console.ReadLine();
}
}
This also is more in line that temp can be only 1, 2 or 3. If it's an int compiler won't warn you if temp gets value of 34.
You can also do this:
string GetText(int temp){
return ((MyEnum)temp).ToString();
}
GetText(2) will return "No"
Related
How from switch to return result return?
Method1, depending on the value of the variable "str_1", selects an additional method to execute.
I get an error:
"Using local variable" s1 ", which is not assigned a value."
Code
public string Method1(string str_1)
{
string s1;
switch (str_1)
{
case "type_1":
s1 = MethodTest();
break;
}
return s1;
}
public string MethodTest()
{
string s = "test";
return s;
}
Thats correct. Switch not necessarily will lead to use your one case you have.
There are need to be performed one of 2 changes:
1)
string s1 = string.Empty; //(provide default value)
2) provide:
switch (str_1)
{
/*...*/
default:
s1 = "...";
break;
string s1 = string.Empty or string s1 = null
It is complaining that it's possible for that value to not be set since there isn't any guarantee that the switch-case statement will be hit.
s1 has the possibility to have never been set to a value. The error will go away if you while declaring your string, you set it equal to a default value:
string s1 = string.Empty;
I see 4 options:
1) string s1= string.Empty;
2) string s1= null;
3) string s1="";
4) You can make a small refactor:
public string Method1(string str_1)
{
switch (str_1)
{
case "type_1":
return MethodTest();
default:
return string.Empty;
}
}
You can avoid local variable. Just decide what are you going to return in default case.
public string Method1(string str_1)
{
switch (str_1)
{
case "type_1":
return MethodTest();
default:
return null;
}
}
string returnString;
switch(Type) {
case 0: returnString = exampleFunction(foo0, out int exitCode); break;
case 1: returnString = exampleFunction(foo1, out int exitCode); break;
case 2: returnString = exampleFunction(foo2, out int exitCode); break;
}
When I write this code, VS displayed me an error that 'A local variable named or function named 'exitCode' is already defined in this scope' for line 4 and 5. So if I want to get more than two variables with different types from exampleFunction, what should I do? If I can't use out in the code, should I use tuple to get returnString and exitCode from the function?
You could declare exitCode variable before the switch. You should initialize it with some value or have default branch in you switch. Otherwise there is a flow by which exitCode will be uninitialized after the switch. Compiler will not pass this. Also don't forget a break after each case:
int exitCode = 0;
string returnString;
switch(Type) {
case 0: returnString = exampleFunction(foo0, out exitCode); break;
case 1: returnString = exampleFunction(foo1, out exitCode); break;
case 2: returnString = exampleFunction(foo2, out exitCode); break;
}
But overall having a method returning two different values (one as return value and second as out parameter) is a bad practice. Consider having some simple class with those values as properties:
class SomeValue
{
public string Foo { get; set; }
public int Code { get; set; }
}
static SomeValue ExampleFunction(string input)
{
return new SomeValue
{
Foo = input,
Code = 1,
};
}
static void Main(string[] args)
{
// ...
SomeValue val = null;
switch (Type)
{
case 0: val = ExampleFunction(foo0); break;
case 1: val = ExampleFunction(foo1); break;
case 2: val = ExampleFunction(foo2); break;
}
}
Instead of declaring foo0, foo1, and foo2, perhaps you should consider using an array, e.g. foo[]. This is usually a good idea whenever you see variable names with ascending numbers like that.
If you do it that way, the problem goes away, and you code is much shorter:
var returnString = exampleFunction(foo[Type], out int exitCode);
If it doesn't make sense within the problem domain for foo0, foo1, and foo2 to live in an array (e.g. their individual names are important), you can still use a temporary array as a map:
var returnString = exampleFunction(
new[] {foo0, foo1, foo2} [Type],
out int exitCode
);
You should declare "exitCode" only for the first time
case 0: returnString = exampleFunction(foo0, out int exitCode); break;
case 1: returnString = exampleFunction(foo1, out exitCode); break;
case 2: returnString = exampleFunction(foo2, out exitCode); break;
Once you declare it "inline", it becomes local variable for that block.
I'm seeing some strange behavior when using a nullable long switch statement in VS2015 Update 1 that I'm not seeing in other Visual Studio releases where it runs as expected.
class Program
{
static void Main(string[] args)
{
NullableTest(-1);
NullableTest(0);
NullableTest(1);
NullableTest(2);
NullableTest(null);
}
public static void NullableTest(long? input)
{
string switch1;
switch (input)
{
case 0:
switch1 = "0";
break;
case 1:
switch1 = "1";
break;
default:
switch1 = "d";
break;
}
string switch2;
switch (input)
{
case -1:
switch2 = "-1";
break;
case 0:
switch2 = "0";
break;
case 1:
switch2 = "1";
break;
default:
switch2 = "d";
break;
}
string ifElse;
if (input == 0)
{
ifElse = "0";
}
else if (input == 1)
{
ifElse = "1";
}
else
{
ifElse = "d";
}
Console.WriteLine("Input = {0}, Switch 1 output = {1}, Switch 2 output = {2}, If Else = {3}", input, switch1, switch2, ifElse);
}
This sample code produces the following output (Aligned for readability):
Input = -1, Switch 1 output = d, Switch 2 output = d, If Else = d
Input = 0, Switch 1 output = 0, Switch 2 output = d, If Else = 0
Input = 1, Switch 1 output = d, Switch 2 output = d, If Else = 1
Input = 2, Switch 1 output = d, Switch 2 output = d, If Else = d
Input = , Switch 1 output = d, Switch 2 output = d, If Else = d
I'm only observing this behavior with Nullable types. Non-nullable types work as expected.
Note that this is not the same behavior that's in this question, and is not caused by this compiler bug that's been fixed in VS2015 Update 1. I've verified that both of those examples run correctly.
It looks like this is caused by this bug, and was fixed with this pull request.
I've tried a recent build of Roslyn and the sample code in the question works as expected now.
Here is the updated version of MSBuild Tools 2015 that has corrected the issue.
This is a bug. I believe it must be a left over of the same bug. You better replace your code with an If to avoid any unexpected behavior.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am a novice C# user, and I am experimenting with lists in Csharp's console application. This list contains 10 numbers, and the order of these numbers are randomized. What I want to do is to make specific text for a specific number which if statements will handle.
For example: If number == 0, the text "Hello" will show up. Or if the number == 3, the text "Goodbye" will show up.
I tried a few things but I got problems like repeated text: http://i.imgur.com/8sCbeLn.jpg?1
Random r = new Random();
int tempValue;
List<int> number = new List<int>();
number.Add(0);
number.Add(1);
number.Add(2);
number.Add(3);
number.Add(4);
number.Add(5);
number.Add(6);
number.Add(7);
number.Add(8);
number.Add(9);
for (int i = 0; i < 10; i++)
{
tempValue = r.Next(0, number.Count);
Console.WriteLine(number[tempValue]);
number.RemoveAt(tempValue);
Console.ReadLine();
}
Please help me getting on the right track.
You can for example use a switch to select strings from a value.
If you get repeated values, I suspect that you used tempValue to select the string, you have to use number[tempValue]:
string text = null;
switch (number[tempValue]) {
case 0: text = "Hello"; break;
case 1: text = "How do you do"; break;
case 2: text = "Howdie"; break;
case 3: text = "Goodbye"; break;
case 4: text = "Bye"; break;
case 5: text = "Hello again"; break;
case 6: text = "Good day"; break;
case 7: text = "Have fun"; break;
case 8: text = "Greatings"; break;
case 9: text = "Goodbye again"; break;
}
Why not add 10 random numbers to a list and then loop through the list, and print using you if statements
Random r = new Random();
List<int> nums= new List<int>();
int numForList = r.Next(0,10);
bool numInList = true;
//add 10 random numbers to a list
for(int i=0;i<10;i++)
{
do
{
if(!nums.Contains(numForList))
{
numInList = false;
nums.Add(numForList);
}
else
{
numForList = r.Next(0,10);
}
} while (numInList == true);
numInList = true;
}
foreach(var num in nums)
{
switch (num)
{
case 0: Console.WriteLine("Hello"); break;
case 1: Console.WriteLine("How do you do"); break;
... //Add more cases here for each possible random number
}
}
How would I make a switch statement populate a list, or comma delimited string?
For example
switch(test)
{
case 0:
"test"
break;
case 1:
"test2"
break;
case 2:
"test3"
break;
}
So my program will go into this statement multiple times. So lets say it goes in there twice and has case 2 and case 1. I woulld like a string value containing the following:
string value = "test3, test2"
Looks like a List<string> would be ideal to hold your values, you can create a comma separated string from that using string.Join():
List<string> myList = new List<string>();
//add items
myList.Add("test2");
//create string from current entries in the list
string myString = string.Join("," myList);
By multiple times, you mean a loop? You can just have a string and concatenate the string using + operator, or you can just have a list and add to it everytime the case condition is satisfied.
But if you mean by conditional flow so that you want case 0, 1 and 2 to all be evaluated, then you can simply omit the break and do the same concatenation like I mentioned above.
private string strValue = string.Empty;
private string StrValue
{
get
{
return strValue ;
}
set
{
StrValue= string.Concat(strValue , ",", value);
}
}
switch(test)
{
case 0:
StrValue = "test"
break;
case1:
StrValue = "test2"
break;
case 2:
StrValue = "test3"
breakl
}
Where ever you used StrValue remove "," if "," comes in the last.
There's a couple ways you can do it, a very simple one is:
string csv = "";
while (yourCriteria) {
string value;
// insert code to get your test value
switch(test)
{
case 0:
value = "test";
break;
case1:
value = "test2";
break;
case 2:
value = "test3";
break;
}
csv += value + ", ";
}
csv = csv.Length > 0 ? csv.Substring(0, csv.Length-2) : "";
Use a loop and a StringBuilder. If you're doing repeated concatenation, StringBuilders are significantly more efficient than naive string concatenation with +.
StringBuilder sb = new StringBuilder();
for(...)
{
switch(test)
{
case 0:
sb.Append("test");
break;
case1:
sb.Append("test2");
break;
case 2:
sb.Append("test3");
break;
}
}