施放然后检查或检查然后施放?

时间:2010-03-31 05:11:02

标签: c# casting

  

可能重复:
  Casting vs using the ‘as’ keyword in the CLR

哪种方法被视为最佳做法?

先施展?

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 个答案:

答案 0 :(得分:19)

如果对象可能属于或不属于您想要的类型,则as运算符(您的第一种方法)在两个方面更好:

  • 可读性和易维护性:您只需指定一次类型
  • 表演:你只进行一次演员,而不是两次。 (琐事:当您使用is关键字时,C#编译器会在内部将其转换为as,即。coke is Cola相当于(coke as Cola) != null

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:4)

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

答案 3 :(得分:3)

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

你为开发人员开发了很多时间,在我看来,它更具可读性首先检查然后再投射......

答案 4 :(得分:1)

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

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

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