为了编写更健壮的DoWithSomeType方法,应该按如下方式改造它:
- static void DoWithSomeType(object obj)
- {
- SecondType secondType = obj as SecondType;
- if (secondType != null)
- {
- // 省略
- }
- }
|
as操作符永远不会抛出异常,如果类型不匹配(被转换对象的运行时类型既不是所转换的目标类型,也不是其派生类型),或者转型的源对象为null,那么转型之后的值也为null。改造前的DoWithSomeType方法会因为引发异常带来效率问题,而使用as后,就可以完美地避免这种问题。
现在,再来看第二种情况,即FirstType是SecondType的基类。在这种情况下,既可以使用强制转型,也可以使用as操作符,代码如下所示:
- class Program
- {
- static void Main(string[] args)
- {
- SecondType secondType = new SecondType() { Name = "Second Type" };
- FirstType firstType1 = (FirstType)secondType;
- FirstType firstType2 = secondType as FirstType;
- }
- }
-
- class FirstType
- {
- public string Name { get; set; }
- }
-
- class SecondType : FirstType
- {
- }
|
但是,即使可以使用强制转型,从效率的角度来看,也建议大家使用as操作符。
知道了强制转型和as之间的区别,我们再来看一下is操作符。DoWithSomeType的另一个版本,可以这样来实现,代码如下所示:
- static void DoWithSomeType(object obj)
- {
- if (obj is SecondType)
- {
- SecondType secondType = obj as SecondType;
- //省略
- }
- }
|
这个版本显然没有上一个版本的效率高,因为当前这个版本进行了两次类型检测。但是,as操作符有一个问题,即它不能操作基元类型。如果涉及基元类型的算法,就需要通过is转型前的类型来进行判断,以避免转型失败。
相关链接:
改善C#程序的157个建议(连载1)
改善C#程序的157个建议(连载2)