施放然后检查或检查然后施放?
可能重复:
使用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; } }
你能看到其他任何方式吗?
如果对象可能属于或不属于您想要的类型,则as
运算符(您的第一种方法)在两个方面更好:
- 可读性和易维护性:您只需指定一次类型
- 表现:你只执行一次演员表演,而不是两次表演。 (Trivia:当你使用
is
关键字时,C#编译器会在内部将其转换as
,即coke is Cola
相当于(coke as Cola) != null
)
如果对象应该始终是所请求的类型,那么只做(Coke)cola
并让它抛出exception,如果不是这样的话。
第一个(第一个通过as)稍微高效一点,所以在这方面,它可能是一个最佳实践。
但是,上面的代码通常会显示一些“代码味道”。 如果可能的话,我会考虑重构遵循此模式的任何代码。 让ICola
提供一种描述方法,让它描述自己。 这样可以避免类型检查和重复代码……
此示例使用一个安全的本地参数,但很多时候类型检查应用于类的字段(成员变量)。 在这种情况下,“as”-then-check是安全的,但“is”-then-cast会造成无偿的竞争条件。
我认为第一种方式更有效: 施放然后检查 ,但……
你为开发人员开发了很多时间,在我看来, 首先检查它然后再进行铸造……
让我把它放在那里。 但我认为两者都不对:)在你的特定例子中,为什么还有一个接口呢? 我会在你的ICola接口上放一个“Describe”方法,然后在你的CocaCola和Pepsi类中实现描述逻辑,实现接口。
所以基本上把这个// some unique
进入实施class。
但是为了回答你的问题,我认为check-then-cast更合适。