Question

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.

Was it helpful?

Solution

        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.

OTHER TIPS

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");

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]();
}

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;
}

C# 7.0 will support switch on types as a part of bigger pattern matching feature. This example is taken from .NET blog post that announces new features:

switch(shape)
{
    case Circle c:
        WriteLine($"circle with radius {c.Radius}");
        break;
    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} square");
        break;
    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} rectangle");
        break;
    default:
        WriteLine("<unknown shape>");
        break;
    case null:
        throw new ArgumentNullException(nameof(shape));
}

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.

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;
}

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...

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

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

if (property.PropertyType == typeof(Boolean))
{
} 
else if (property.PropertyType == typeof(String))
{
}
else if (...)
{
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top