可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Suppose I have a bunch of static fields and I want to use them in switch:
public static string PID_1 = "12";
public static string PID_2 = "13";
public static string PID_3 = "14";
switch(pid)
{
case PID_1:
//Do something 1
break;
case PID_2:
//Do something 2
break;
case PID_3:
//Do something 3
break;
default:
//Do something default
break;
}
Since C# doesn't allow non-const statement inside switch. I want to understand what is the intention of this kind of design. How should I do something like above in c#?
回答1:
It looks like those string values should simply be constant.
public const string PID_1 = "12";
public const string PID_2 = "13";
public const string PID_3 = "14";
If that's not an option (they are actually changed at runtime), then you can refactor that solution into a series of if/else if statements.
As to why the case statements need to be constant; by having them be constant it allows the statement to be much more heavily optimized. It is actually more efficient than a series of if/else if statements (although not dramatically so if you don't have lots of conditional checks that take a long time). It will generate the equivalent of a hash table with the case statement values as keys. That approach couldn't be used if the values can change.
回答2:
... C# doesn't allow non-const statement inside switch...
If you can't use:
public const string PID_1 = "12";
public const string PID_2 = "13";
public const string PID_3 = "14";
You can use a dictionary :)
....
public static string PID_1 = "12";
public static string PID_2 = "13";
public static string PID_3 = "14";
// Define other methods and classes here
void Main()
{
var dict = new Dictionary<string, Action>
{
{PID_1, ()=>Console.WriteLine("one")},
{PID_2, ()=>Console.WriteLine("two")},
{PID_3, ()=>Console.WriteLine("three")},
};
var pid = PID_1;
dict[pid]();
}
回答3:
Case argument should be constant on compile-time.
Try to use const
instead:
public const string PID_1 = "12";
public const string PID_2 = "13";
public const string PID_3 = "14";
回答4:
I'm assuming there's a reason you didn't declare those variables as const
. That said:
The switch
statement is just shorthand for a bunch of if / else if
statements. So if you can guarantee that PID_1
, PID_2
, and PID_3
will never be equal, the above is equivalent to this:
if (pid == PID_1) {
// Do something 1
}
else if (pid == PID_2) {
// Do something 2
}
else if (pid == PID_3) {
// Do something 3
}
else {
// Do something default
}
回答5:
The canonical way to approach this -- if your static fields are not actually constants -- is to use a Dictionary<Something, Action>
:
static Dictionary<string, Action> switchReplacement =
new Dictionary<string, Action>() {
{ PID_1, action1 },
{ PID_2, action2 },
{ PID_3, action3 }};
// ... Where action1, action2, and action3 are static methods with no arguments
// Later, instead of switch, you simply call
switchReplacement[pid].Invoke();
回答6:
Why you don't use enum ?
Enum keyword:
http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx
In your case it can be easily handled over enum:
public enum MyPidType
{
PID_1 = 12,
PID_2 = 14,
PID_3 = 18
}