"as"Versus"is"with Cast

Mat*_*gen 2 c# performance casting

我经常发现自己需要switch打字.我知道这有很多关于Roslyn的讨论,但是由于我正在处理生产代码,我只是对已经存在的选项有一个标准的实践/性能问题:isas.

鉴于课程,

abstract class Foo { }
class Bar : Foo { }
class Tada : Foo { }
Run Code Online (Sandbox Code Playgroud)

以下模式之间是否存在真正的差异?

Foo toUse = ...;

if (toUse != null)
{
    Bar barInstance = toUse as Bar;

    if (barInstance != null)
    {
        // use barInstance
    }
    else
    {
        Tada tadaInstance = toUse as Tada;

        if (tadaInstance != null)
        {
            // use tadaInstance
        }
        else
        {
            // Check whatever other types there are, or throw a NotImplementedException
        }
    }
}
else
{
    // handle the null case
}
Run Code Online (Sandbox Code Playgroud)

相比于

Foo toUse = ...;

if (toUse != null)
{
    Bar barInstance = toUse as Bar;

    if (toUse is Bar)
    {
        Bar barInstance = (Bar)toUse;

        // use barInstance
    }
    else if (toUse is Tada)
    {
        Tada tadaInstance = (Tada)toUse;

        // use tadaInstance
    }
    else
    {
        // Check whatever other types there are, or throw a NotImplementedException
    }
}
else
{
    // handle the null value
}
Run Code Online (Sandbox Code Playgroud)

显然,错别字允许,这两者具有相同的影响.他们应该做同样的事情.但这里有性能问题吗?我总是很欣赏第一种模式的单一操作性质,但它太乱了.更不用说,它会将所有内容都放在范围内,因此您可以使用包含的案例越多,设置越混乱.

as真的只是一个语法快捷方式吗?

if (value is type)
    return (type)value;
else
    return null;
Run Code Online (Sandbox Code Playgroud)

或者它在编译器读取方式上有所不同?

编辑

只是非常清楚,因为这里有可理解和合理的关注,我不会编写需要依赖性能的代码.这只是理论上的好奇心.更不用说了,我更愿意意识到我为可读性做出的性能牺牲,而不是盲目地做,尽管我每次都会接受它.

Ree*_*sey 8

使用as技术上比is使用演员更高效.发生的总操作较少.

出于实际目的,速度差异在现实世界中几乎无法衡量,因此在您的情况下使用更易于维护/可读的版本会更好.

但是,针对类型的大型检查通常是设计问题的标志.您可能需要考虑重新考虑您的设计以完全阻止检查.泛型或虚方法调用通常可以完全消除对此类检查的需要.