开发者

How to use switch-case on a Type? [duplicate]

开发者 https://www.devze.com 2023-04-07 14:05 出处:网络
This question alr开发者_C百科eady has answers here: Closed 10 years ago. Possible Duplicate: Is there a better alternative than this to 'switch on type'?
This question alr开发者_C百科eady has answers here: Closed 10 years ago.

Possible Duplicate:

Is there a better alternative than this to 'switch on type'?

I need to iterate through all properties of my class and to check if its type of int the i need to do something, if its string .. then do something. I need it using switch-case. Here i am using switch in the following manner, but it asks for some constant. see the code below:

 public static bool ValidateProperties(object o)
{
    if(o !=null)
    {
        var sourceType = o.GetType();
        var properties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Static);
        foreach (var property in properties)
        {
            var type = property.GetType();
            switch (type)
            {
                *case typeof(int):* getting error here
                    // d
            }
        }
    }
}

Also i want to know , what check should I use, typeof(int) or typeof(Int32)?


You cannot use a switch block to test values of type Type. Compiling your code should give you an error saying something like:

A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type

You'll need to use if-else statements instead.

Also: typeof(int) and typeof(Int32) are equivalent. int is a keyword and Int32 is the type name.

UPDATE

If you expect that most types will be intrinsic you may improve performance by using a switch block with Type.GetTypeCode(...).

For example:

switch (Type.GetTypeCode(type))
{
    case TypeCode.Int32:
        // It's an int
        break;

    case TypeCode.String:
        // It's a string
        break;

    // Other type code cases here...

    default:
        // Fallback to using if-else statements...
        if (type == typeof(MyCoolType))
        {
            // ...
        }
        else if (type == typeof(MyOtherType))
        {
            // ...
        } // etc...
}


A good and extensible way to do this is to make a dictionary of types and delegates of appropriate type, based on what you want to do with values of that type.

For example:

var typeProcessorMap = new Dictionary<Type, Delegate>
{
    { typeof(int), new Action<int>(i => { /* do something with i */ }) },
    { typeof(string), new Action<string>(s => { /* do something with s */ }) },
};

And then:

void ValidateProperties(object o)
{
    var t = o.GetType();
    typeProcessorMap[t].DynamicInvoke(o); // invoke appropriate delegate
}

This solution is extensible, configurable even at run time, and as long as you keep the keys and types of delegate values in typeProcessorMap correctly matched is also type safe.

See it in action.


Usually, the easiest solution is to switch on the type name:

switch (type.Name)
{
    case "Int32":
    ...
}


This "answer" is an elaboration for Jon's answer. (Marking CW)

For the record, DynamicInvoke is a bit slow. To illustrate this, consider the following program:

void Main()
{
    Func<int, string> myFunc = i => i.ToString();
    myFunc.DynamicInvoke(1);   // Invoke once so initial run costs are not considered
    myFunc(1);

    Stopwatch stopwatch = new Stopwatch();

    stopwatch.Start();
    for (int i = 0; i < 1000000; i++)
        myFunc.DynamicInvoke(1);
    stopwatch.Stop();

    var elapsed = stopwatch.Elapsed;

    stopwatch.Restart();
    for (int i = 0; i < 1000000; i++)
        myFunc(1);
    stopwatch.Stop();

    var elapsed2 = stopwatch.Elapsed;

    Console.WriteLine("DynamicInvoke: " + elapsed);
    Console.WriteLine("Direct Invocation: " + elapsed2);
}

Prints out:

DynamicInvoke: 00:00:03.1959900
Direct Invocation: 00:00:00.0735220

Which means that DynamicInvoke (in this simple case) is 42 times slower than direct invocation.

0

精彩评论

暂无评论...
验证码 换一张
取 消