Is there a better alternative than this to 'sw

2018-12-31 07:15发布

Seeing as C# can't switch on a Type (which I gather wasn't added as a special case because is-a relationships mean that more than one distinct case might apply), is there a better way to simulate switching on type than this?

void Foo(object o)
{
    if (o is A)
    {
        ((A)o).Hop();
    }
    else if (o is B)
    {
        ((B)o).Skip();
    }
    else
    {
        throw new ArgumentException("Unexpected type: " + o.GetType());
    }
}

25条回答
情到深处是孤独
2楼-- · 2018-12-31 07:53

As per C# 7.0 specification, you can declare a local variable scoped in a case of a switch:

object a = "Hello world";
switch (a)
{
    case string _:
        // The variable 'a' is a string!
        break;
    case int _:
        // The variable 'a' is an int!
        break;
    case Foo _:
        // The variable 'a' is of type Foo!
        break;
}

By any chance, are you asking for why the variable is declared as string _? Why the underscore?

Well, another feature introduced with C# 7.0 is that you can name as such a variable you never reference to. So, you can't reference the variable _. It is good in many scenarios such that the OP asked for, since he want just to check the type and not to get also a casted reference. Otherwise, you can rename that variable and use it as a reference as you want.


This is the best way to do such a thing, because it involves just casting and push-on-the-stack operations, which are the fastest operations an interpreter can run just after bitwise operations and boolean conditions.

Comparing this to a Dictionary<K, V>, here's much less memory usage: holding a dictionary requires more space in the RAM and some computation more by the CPU for creating two arrays (one for keys and the other for values) and gathering hash codes for the keys to put values to their respective keys.

So, for as far I know, I don't believe that a faster way could exists even if you don't want to use just an if-then-else block with the is operator as follows:

object a = "Hello world";
if (a is string)
{
    // The variable 'a' is a string!
} else if (a is int)
{
    // The variable 'a' is an int!
} // etc.
查看更多
登录 后发表回答