views:

753

answers:

10

How can I make this work?

switch(property.PropertyType){
    case typeof(Boolean): 
        //doStuff
        break;
    case typeof(String): 
        //doOtherStuff
        break;
    default: break;
}

I don't want to use the name since string comparing for types is just awfull and can be subject to change.

A: 

i think that you must use string comparing.

SelvirK
A: 

Do not worry about using strings within a switch because if you have several the compiler will automatically convert it into a hash lookup giving decent performance despite it looking pretty aweful.

The problem of type strings changing can be solved by making it into an explicit hash lookup yourself and populating the constents of the hash in a static constructor. That way the hash is populate with the correct strings at runtime so they remain correct.

Phil Wright
A: 

You can't do this with switch in c# as the case has to be constant.

What is wrong with:

if(property.PropertyType == typeof(bool)) {
    //dostuff;
}
else if (property.PropertyType == typeof(string)) {
    //do other stuff;
}
Sam Meldrum
A: 

Just use the normal if/else if/else pattern:

if (property.PropertyType == typeof(Boolean))
{
} 
else if (property.PropertyType == typeof(String))
{
}
else if (...)
{
}
+7  A: 
        System.Type propertyType = typeof(Boolean);
        System.TypeCode typeCode = Type.GetTypeCode(propertyType);
        switch (typeCode)
        {
            case TypeCode.Boolean:
                //doStuff
                break;
            case TypeCode.String:
                //doOtherStuff
                break;
            default: break;
        }

You can use an hybrid approach for TypeCode.Object where you dynamic if with typeof. This is very fast because for the first part - the switch - the compiler can decide based on a lookup table.

smink
Will not work if you want to compare anything other than the simple built in types because TypeCode is an enumeration that does not container anything but simple types like bool,int32 etc...
Phil Wright
Of course that is true. But being out of scope on the example i ommitted in the first place. Added later to make clear that point. Thanks.
smink
Well, in my particular case it will only be base types.
borisCallens
josefresno
+3  A: 

You can't. What you can do is create a mapping between Types and a delegate using a dictionary:

var TypeMapping = new Dictionary<Type, Action<string>>(){
    {typeof(string), (x)=>Console.WriteLine("string")},
    {typeof(bool), (x)=>Console.WriteLine("bool")}
};



string s = "my string";

TypeMapping[s.GetType()]("foo");
TypeMapping[true.GetType()]("true");
pb
A: 

I recently had to do something similar and using switch wasn't an option. Doing an == on the typeof(x) is fine, but a more elegant way might be to do something like this:

if(property.PropertyType is bool){
  //dostuff;
}
else if (property.PropertyType is string){
    //do other stuff;
}

But, I'm not certain that you can use the "is" keyword in this way, I think it only works for objects...

xan
+1  A: 

I think what you are looking for here is a good Map. Using delegates and a Generic IDictionary you can do what you want.

Try something like this:

private delegate object MyDelegate();

private IDictionary<Type, MyDelegate> functionMap = new IDictionary<Type, MyDelegate>();

public Init()
{
  functionMap.Add(typeof(String), someFunction);
  functionMap.Add(tyepof(Boolean), someOtherFunction);
}

public T doStuff<T>(Type someType)
{
   return (T)functionMap[someType]();
}
Josh
A: 

I personally prefer the Dictionary<Type, other> approach the most... I can even provide you another example: http://www.timvw.be/presenting-namevaluecollectionhelper/

In case you insist on writing a switch-case statement you could use the Type name...

switch(blah.PropertyType.FullName)
{
case typeof(int).FullName: break;
case typeof(string).FullName: break;
}

timvw
A: 

About the stringmatching: it was one of the reqs in the question to not do it through stringmatching.

The dictionary is an approach I will use when I put this entire serialization algorithm in its own library. As for now I will first try the typeCode as my case only uses basic types. If that doesn't work I will go back to the swarm of if/elses :S

Before ppl ask me why I want my own serialization: 1) .net xml serialization doesn't serialize properties without setters 2) serialization has to comply to some legacy rules

borisCallens
You can bypass the properties limitation by adding an empty set.public string MyProp{ get{return foo;} set{;}}
pb