using switch statements with constants or enumerations? (Which is better)? C# - c#

HI, I've got a simple question, but one that has been bugging me for a while.
Question:
When using switch statements in C#, is it considered better practice to use enums over constants or vice versa? Or is it a matter of preference? I ask this because many people seem to like using enums, but when you are switching on an int value, you have to cast each of the values contained in the enum to an int, even if you specify the type of enum.
Code Snippet:
class Program
{
enum UserChoices
{
MenuChoiceOne = 1,
MenuChoiceTwo,
MenuChoiceThree,
MenuChoiceFour,
MenuChoiceFive
}
static void Main()
{
Console.Write("Enter your choice: ");
int someNum = int.Parse(Console.ReadLine());
switch (someNum)
{
case (int)UserChoices.MenuChoiceOne:
Console.WriteLine("You picked the first choice!");
break;
// etc. etc.
}
}
}
Is there some way you can create an instance of the enum and just cast the whole enum to an int?
Thanks!

Why not do this instead?
UserChoices choice = (UserChoices)int.Parse(Console.ReadLine());
switch (choice)
{
case UserChoices.MenuChoiceOne:
// etc...
Then you only need to cast once.
Update: fixed bug in code!

I think the preference of enums over constants is because of readability and not because of performance. I find it easier to read enums in code (in general and not just in switch statements), than to read/understand constants and their usage.
and btw, you don't have to cast every case, you can just cast your switch.
switch((UserChoices)someEnum)
{
...

I believe you can simply do:
switch((UserChoices)someNum)
{
case UserChoices.MenuChoiceOne:
break;
default:
throw Exception // whatever here
}

Related

Better If statement with type checking C#

I'm currently working on a .NET 4.7.1 application. I have an If-statement to check the data type and call an handler method accordingly.
My current If statement looks like this:
// object msg = MyHelper.Deserialize(xmlString);
if (msg is Tomato) Handle_Tomato((Tomato)msg);
if (msg is Apple) Handle_Apple((Apple)msg);
if (msg is Banana) Handle_Banana((Banana)msg);
if (msg is Orange) Handle_Orange((Orange)msg);
msg is basically an object deserialized from a string.
I was wondering, if there is a better way to write my if statements?
Thank you very much!
As Sweeper mentions in the comments, from C# 7.0 you can use the The is type pattern expression
if (msg is Tomato tomato) Handle_Tomato(tomato);
You could also use pattern matching with a switch statement (Type pattern) since C# 7.0
The type pattern enables concise type evaluation and conversion. When
used with the switch statement to perform pattern matching, it tests
whether an expression can be converted to a specified type and, if it
can be, casts it to a variable of that type.
switch(msg)
{
case Tomato tomato : Handle_Tomato(tomato); break;
case Apple apple : Handle_Apple(apple); break;
...
}
I'd strongly suggest not to do such checks. What if in the future there are dozens of different types? Your if statement will increase and be unmaintainable. What if the type changes? You'd have to change all the if statements as well.
You could solve this by using an interface. You already have the classes.
interface IHandler
{
void Execute();
}
class Orange : IHandler
{
public void Execute()
{
// do your orange stuff
}
}
class Tomato : IHandler
{
public void Execute()
{
// do your tomato stuff
}
}
It can be called like this.
if (msg is IHandler) ((IHandler)msg).Execute();
I think the easiest would be to use a switch/case
switch (msg)
{
case Tomato t:
Handle_Tomato(t);
break;
case Apple a:
Handle_Apple(a);
break;
case Banana b:
Handle_Banana(b);
break;
case Orange o:
Handle_Orange(o);
break;
}
Use a dictionary. I foresee your if will explode with new cases in future, generally speaking, walls of if and large switch statements are bad code. In a similar situation I created something like this:
private static readonly Dictionary<RuntimeTypeHandle, Action<object>> handleMsgImplementations = new Dictionary<RuntimeTypeHandle, Action<object>>
{
{ typeof(Tomato).TypeHandle, x => Handle_Tomato((Tomato)x) },
// etc...
};
// Then instead of if, use this (prepare a catch for Invalid Key or use a TryGetValue)
handleMsgImplementations[msg.GetType().TypeHandle](msg);
I get TypeHandle because I like to use a value type for the key.
EDIT: #TheGeneral answer is the best, also, the C# compiler creates a dictionary under the hood when the amount cases starts to damage performance. I keep my answer because I believe adds value.

C# Simple Type w/ Generic Type

I want to do different things with a generic type given that it is a byte array, int, etc.
public void GenericType<T>(T Input)
{
switch (typeof(T))
{
case (typeof(byte[])):
break;
case (typeof(int)):
case (typeof(float)):
case (typeof(long)):
break;
case (typeof(string)):
break;
default:
throw new Exception("Type Incompatability Error");
break;
}
}
Sandbox.cs(12,13): error CS0151: A switch expression of type `System.Type' cannot be converted to an integral type, bool, char, string, enum or nullable type
add:
My specific case has some code that is generic and some code that is specific. I also have one where I do not actually pass a T variable. Solutions thus far work if there is a variable.
public void GenericType<T>()
Not being terribly experienced, what is the best practice in C#?
Thank you.
You can do this with switch using pattern matching:
switch(Input)
{
case int i:
// do something with i
case string x:
// do something with x
}
You might try something like
if (Input is int i) { DoSomething(i) ; }
else if (Input is long l) { DoSomething(l) ; }
Best? Maybe. Works? Yup.
You are effectively calling System.Object GenericType in this example.

How to use switch case block in c# properly?

I have a switch case statements in c#, here all the cases i made as private constants ,is there any bad programming practice going on here, or do i need to use enumeration here and enumerator in case block.Only three constants i showed here, i have ten constants and ten case block
private const String FEASIBLESIZE = "Total FEASIBLESIZE";
private const String AVAILABLESIZE = "Total AVAILABLESIZE";
private const String EXCESSSIZE = "Total EXCESSSIZE";
.
.
switch (value.ToString())
{
case FEASIBLESIZE:
Level.Add(TEAMSIZE, test.ToString());
break;
case AVAILABLESIZE:
Level.Add(BROADSIZE, test.ToString());
break;
case EXCESSSIZE:
Level.Add(NARROWSIZE, test.ToString());
break;
.
.
.
Aside from the horrible formatting it looks roughly okay. Of course that's a bit hard to tell without actually knowing your code. Darin is correct though, in that you're not adhering to the default naming conventions (all caps is a no-go anywhere in C#).
But I have seen much worse, if that's any consolation.
What you are doing looks like something that can be replaced using a Dictionary<string,string> mapping from one size type to another.
var sizeMap = new Dictionary<string,string>();
sizeMap.Add(FEASIBLESIZE, TEAMSIZE);
sizeMap.Add(AVAILABLESIZE, BROADSIZE);
sizeMap.Add(EXCESSSIZE, NARROWSIZE);
And instead of the switch:
Level.Add(sizeMap[value.ToString()], test.ToString());
Please try to scope the case with curly braces this is just individual style but helps when lines of code grows up and also always use the default: too
case FEASIBLESIZE:
{
Level.Add(TEAMSIZE, test.ToString());
break;
}
default:
///...
break;
Your constants appear to be a candidate for Enum, I would go for Enum rather than const here....
Bad Programming Practice:
private const String FEASIBLESIZE = "Total FEASIBLESIZE";
Good Programming Practice:
private const String FEASIBLE_SIZE = "Total FEASIBLESIZE";
Better Programming Practice:
private const String FeasibleSize = "Total FEASIBLESIZE";

C# variable scopes and the "switch" statement?

This kind of code would normally work in PHP, but since the scope is much more strict in C#, it's not. I can't figure out a way to write this code without repeating myself.
static double Cube()
{
Console.Write("Enter the side length of the cube: ");
try
{
double x = Convert.ToDouble(Console.Read());
return Math.Pow(x, 3);
}
catch (FormatException)
{
Console.WriteLine("Invalid input, please enter a number.");
Cube();
}
return 1;
}
..Later in Main():
switch (choice)
{
case 0:
return;
case 1:
double final = Cube();
break;
default:
Console.WriteLine("Please enter 0 or 1.");
Main();
break;
}
Console.WriteLine("The volume is: {0}", Convert.ToString(final));
The Cube() method works fine, but it's messy in my opinion (return 1 at the end to make the compiler happy). But an error comes up saying The name 'final' does not exist in the current context. It can't find final. So the only way to make this work that I'm seeing is to put the Console.WriteLine statement right after the double final = Cube().
I've also tried declaring double final; outside the switch, then just setting final inside each case, but that hasn't worked either.
Thanks!
You're right: this is a mess. Start over.
Your fundamental problem is that you're not separating your concerns. You have a method that does user input, input validation, retry logic and math all at the same time. You should rather make methods for each.
Also, use TryParse to handle the failure case, not exception handling.
Finally, recursion is completely the wrong tool to use. A problem must have the following characteristics to be solved by recursion:
A trivial base case.
Can be reduced to a set of smaller problems.
Solutions to smaller problems can be combined to solve larger problems.
Making a problem smaller repeatedly eventually gets to the trivial case.
Your problem has none of these properties, so recursion is automatically the wrong tool. The tool you want is a loop.
static void Main()
{
double x = ObtainDoubleFromUser(
"Enter the side length of the cube: ",
"Please enter a number: ");
Console.WriteLine("The volume is {0}", Cube(x));
}
static double ObtainDoubleFromUser(string firstMessage, string failureMessage)
{
Console.Write(firstMessage);
while(true)
{
double result;
if (Double.TryParse(Console.Read(), out result))
return result;
Console.Write(failureMessage);
}
}
static double Cube(double x)
{
return Math.Pow(x, 3);
}
Does that all make sense? You want to avoid recursion and exception handling if you possibly can. And keep your concerns separated.
If you want to access final from outside the switch scope, you'll have to declare it outside that scope too. If you reference final and there are code paths that allow not setting a value to final, then the compiler will be "angry".
In php, final would magically be 0 when you don't assign anything to it. Try declaring final before the switch, and then assign a value to it at each case statement including the default case.
Place the variable declaration before your switch statement:
double final = 0.0;
switch(choice)
{
...
}
Then just use the variable in your switch statement:
case 1:
final = Cube();
break;
In C#, variables must be declared before they can be used. In your code, the declaration was limited to the scope of the switch statement. Declaring the variable prior to the switch statement ensures that its in the scope of the method, allowing it to be used inside and after the switch statement.

c# performance: type comparison vs. string comparison

Which is faster? This:
bool isEqual = (MyObject1 is MyObject2)
Or this:
bool isEqual = ("blah" == "blah1")
It would be helpful to figure out which one is faster. Obviously, if you apply .ToUpper() to each side of the string comparison like programmers often do, that would require reallocating memory which affects performance. But how about if .ToUpper() is out of the equation like in the above sample?
I'm a little confused here.
As other answers have noted, you're comparing apples and oranges. ::rimshot::
If you want to determine if an object is of a certain type use the is operator.
If you want to compare strings use the == operator (or other appropriate comparison method if you need something fancy like case-insensitive comparisons).
How fast one operation is compared to the other (no pun intended) doesn't seem to really matter.
After closer reading, I think that you want to compare the speed of string comparisions with the speed of reference comparisons (the type of comparison used in the System.Object base type).
If that's the case, then the answer is that reference comparisons will never be slower than any other string comparison. Reference comparison in .NET is pretty much analogous to comparing pointers in C - about as fast as you can get.
However, how would you feel if a string variable s had the value "I'm a string", but the following comparison failed:
if (((object) s) == ((object) "I'm a string")) { ... }
If you simply compared references, that might happen depending on how the value of s was created. If it ended up not being interned, it would not have the same reference as the literal string, so the comparison would fail. So you might have a faster comparison that didn't always work. That seems to be a bad optimization.
According to the book Maximizing .NET Performance
the call
bool isEqual = String.Equals("test", "test");
is identical in performance to
bool isEqual = ("test" == "test");
The call
bool isEqual = "test".Equals("test");
is theoretically slower than the call to the static String.Equals method, but I think you'll need to compare several million strings in order to actually detect a speed difference.
My tip to you is this; don't worry about which string comparison method is slower or faster. In a normal application you'll never ever notice the difference. You should use the way which you think is most readable.
The first one is used to compare types not values.
If you want to compare strings with a non-sensitive case you can use:
string toto = "toto";
string tata = "tata";
bool isEqual = string.Compare(toto, tata, StringComparison.InvariantCultureIgnoreCase) == 0;
Console.WriteLine(isEqual);
How about you tell me? :)
Take the code from this Coding Horror post, and insert your code to test in place of his algorithm.
Comparing strings with a "==" operator compares the contents of the string vs. the string object reference. Comparing objects will call the "Equals" method of the object to determine whether they are equal or not. The default implementation of Equals is to do a reference comparison, returning True if both object references are the same physical object. This will likely be faster than the string comparison, but is dependent on the type of object being compared.
I'd assume that comparing the objects in your first example is going to be about as fast as it gets since its simply checking if both objects point to the same address in memory.
As it has been mentioned several times already, it is possible to compare addresses on strings as well, but this won't necessarily work if the two strings are allocated from different sources.
Lastly, its usually good form to try and compare objects based on type whenever possible. Its typically the most concrete method of identification. If your objects need to be represented by something other than their address in memory, its possible to use other attributes as identifiers.
If I understand the question and you really want to compare reference equality with the plain old "compare the contents": Build a testcase and call object.ReferenceEquals compared against a == b.
Note: You have to understand what the difference is and that you probably cannot use a reference comparison in most scenarios. If you are sure that this is what you want it might be a tiny bit faster. You have to try it yourself and evaluate if this is worth the trouble at all..
I don't feel like any of these answers address the actual question. Let's say the string in this example is the type's name and we're trying to see if it's faster to compare a type name or the type to determine what it is.
I put this together and to my surprise, it's about 10% faster to check the type name string than the type in every test I ran. I intentionally put the simplest strings and classes into play to see if it was possible to be faster, and turns out it is possible. Not sure about more complicated strings and type comparisons from heavily inherited classes. This is of course a micro-op and may possibly change at some point in the evolution of the language I suppose.
In my case, I was considering a value converter that switches based on this name, but it could also switch over the type since each type specifies a unique type name. The value converter would figure out the font awesome icon to show based on the type of item presented.
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApp1
{
public sealed class A
{
public const string TypeName = "A";
}
public sealed class B
{
public const string TypeName = "B";
}
public sealed class C
{
public const string TypeName = "C";
}
class Program
{
static void Main(string[] args)
{
var testlist = Enumerable.Repeat(0, 100).SelectMany(x => new object[] { new A(), new B(), new C() }).ToList();
int count = 0;
void checkTypeName()
{
foreach (var item in testlist)
{
switch (item)
{
case A.TypeName:
count++;
break;
case B.TypeName:
count++;
break;
case C.TypeName:
count++;
break;
default:
break;
}
}
}
void checkType()
{
foreach (var item in testlist)
{
switch (item)
{
case A _:
count++;
break;
case B _:
count++;
break;
case C _:
count++;
break;
default:
break;
}
}
}
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 100000; i++)
{
checkTypeName();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
sw.Restart();
for (int i = 0; i < 100000; i++)
{
checkType();
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
}
}

Categories