tags:

views:

190

answers:

4

Hello,

Is it possible to retrieve programmatically all the case of a switch ? I don't have any idea, maybe by IL but not sure how to do ...

In fact my global issue is the following : I got a siwtch case with string as property name. The method is very important and a regression is not allowed. I don't want a refactoring breaking this, so I want a method to test that all case string are in fact real properties of my objects. (NB : the default value return something so I can't throw an exceptino for a refactored invalid value).

+1  A: 

Getting the values in a switch would not be trivial...

If you use an enum in the switch instead of strings, you can easily get the values of the enum using Enum.GetValues.

Guffa
+2  A: 

There are ways to avoid using property names as string directly in your code. I've posted a code snippet here.

Then, instead of using a switch statement, implement something like this:

private IDictionary<string, Action> _actions;

public void RegisterAction(string propertyName, Action action)
{
    _actions.Add(propertyName, action);
}

public void DoSomething(string propertyName)
{
    _actions[propertyName]();
}

When you call both methods, be sure that you use the Member class of the code snippet (see link) instead of using the property names directly. So you can make sure, that your code is refactoring-proof, because it does not contain any "magic strings".

Best Regards

Oliver Hanappi
Finally, used the code displayed on the linked post and the dictionnary as suggested, thx !
Toto
+2  A: 

In IL, a switch statement compiles to something like this:

// ...
L_000c: ldloc.1 
L_000d: ldstr "case1"
L_0012: call bool [mscorlib]System.String::op_Equality(string, string)
L_0017: brtrue.s L_0035
L_0019: ldloc.1 
L_001a: ldstr "case2"
L_001f: call bool [mscorlib]System.String::op_Equality(string, string)
L_0024: brtrue.s L_0042
L_0026: ldloc.1 
L_0027: ldstr "case3"
L_002c: call bool [mscorlib]System.String::op_Equality(string, string)
L_0031: brtrue.s L_004f
// ...

It would be a fair amount of work to write code that could analyze this properly in all cases.

The only way I can see to test this is to actually cover all cases and ensure you don't end up with a null PropertyInfo. If the code you are working with is very important and can't fail, it's probably pretty dangerous to use reflection in any case. Can you move to a more type-safe design?

bobbymcr
And if the switch becomes to large, the C# compiler will generate a hashtable as switch implementation... Not very IL friendly indeed :)
Bert Huijben
On the contrary, if the switch isn't small it's a piece of cake to get the hashtable — see my answer below.
Anton Tykhyy
Sure I didn't thought that it would be easy to do it. In fact the code can throw an exception, I just don't want it to be ok with an invalid string as property.
Toto
A: 

Write a script in AWK or Perl or whatever to check the source itself, and run it before every build.

CannibalSmith