首页 文章

施放然后检查或检查然后施放? [重复]

提问于
浏览
15

可能重复:使用CLR中的'as'关键字进行转换

哪种方法被认为是最佳做法?

先投?

public string Describe(ICola cola)
{
    var coke = cola as CocaCola;
    if (coke != null)
    {
        string result;
        // some unique coca-cola only code here.
        return result;
    }
    var pepsi = cola as Pepsi;
    if (pepsi != null)
    {
        string result;
        // some unique pepsi only code here.
        return result;
    }
}

或者我应该先检查,然后再投?

public string Describe(ICola cola)
{
    if (cola is CocaCola)
    {
        var coke = (CocaCola) cola;
        string result;
        // some unique coca-cola only code here.
        return result;
    }
    if (cola is Pepsi)
    {
        var pepsi = (Pepsi) cola;
        string result;
        // some unique pepsi only code here.
        return result;
    }
}

你能看到其他任何方式吗?

5 回答

  • 4

    如果对象可能是您想要的类型,那么 as 运算符(您的第一种方法)在两个方面更好:

    • 可读性和易维护性:您只需指定一次类型

    • 表现:你只进行一次施法,而不是两次 . (琐事:当你使用 is 关键字时,C#编译器在内部将其转换为 as ,即 . coke is Cola 相当于 (coke as Cola) != null

    如果对象应始终是请求的类型,那么只需执行 (Coke)cola 并让它抛出异常,如果不是这样的话 .

  • 1

    第一个(第一个通过as)效率稍高,所以在这方面,它可能是最好的做法 .

    但是,上面的代码通常会显示一些"code smell" . 如果可能的话,我会考虑重构遵循此模式的任何代码 . 让 ICola 提供一种描述方法,并让它描述自己 . 这避免了类型检查和重复代码......

  • 19

    此示例使用一个安全的本地参数,但很多时候将类型检查应用于类的字段(成员变量) . 在这种情况下,“as”-then-check是安全的,但是“is”-then-cast会造成无偿的竞争条件 .

  • 3

    我认为第一种方式更有效:施放然后检查,但......

    你为开发人员开发了很多时间,在我看来,首先检查它然后再进行铸造......

  • 7

    让我把它放在那里 . 但我认为两者都不对:)在你的特定例子中,为什么还有一个接口呢?我会在您的ICola接口上放置一个“Describe”方法,然后在实现该接口的CocaCola和Pepsi类中实现describe逻辑 .

    所以基本上把 // some unique <some cola> only code here. 放到实现类中 .

    但是为了回答你的问题,我认为check-then-cast更合适 .

相关问题