尽量采用as操作符而不是旧式C风格做强制类型转换
http://www.cnblogs.com/JiangSoney/archive/2009/08/07/1541488.html
MSDN: https://msdn.microsoft.com/zh-cn/vstudio/cc488006
C#是一种强数据类型语言。(一种总是强制类型定义的语言。如果你有一个整数,如果不显示地进行转换,你不能将其视为
一个字符串。)好的编程习惯提醒我们要尽量避免使用强制转换,但是有的时候我们是无法避免的。
强制转换适用情况:源变量和目标变量兼容。即使这样也存在数据丢失的风险,因为目标变量的类型大小比源变量小或者目
标变量是源变量的一个基类。
在c#里,你有两种方法来实现强制转化:
A、采用as运算符;
B、旧式的C风格“(type)object”。
那么我们应该什么时候采用as运算符,什么时候采用旧式C风格强制类型转换?
先来看一段代码:
public class Base
{
public void Read()
{
Console.WriteLine("read");
}
} public class Derived : Base
{
public void Write()
{
Console.WriteLine("Derived write");
}
} public class CTest
{
public void check_c() // 采用旧式C风格的强制转换
{
object der = new Derived();
try
{
Base bas = (Base)der;
if (null != bas)
{
bas.Read();
}
else
{
Console.WriteLine("C Cast failed!");
}
}
catch (Exception error)
{
Console.WriteLine(error.ToString());
}
}
public void check_as() // 采用as运算符强制转换
{
object obj = new Derived();
Base bas = obj as Base;
if (null != bas)
{
bas.Read();
}
else
{
Console.WriteLine("As Cast failed!");
} }
}
显然,如果要你从check_c()和check_as()方法中选择,你肯定会选后者。因为两者相比较后者具有:
1、 减少了性能开销(try/catch结构的性能开销)
2、 精简了代码
3、 更安全,as转换不会有异常抛出,如果转换失败,也会安全的返回null。
什么情况下使用C风格强制转换
1、用户定义类型转换(http://msdn.microsoft.com/zh-cn/vstudio/ms173105.aspx)。
public class Wheel
{
public void Say()
{
Console.WriteLine(" I'm a wheel.");
}
}
public class Car
{
private Wheel _wheel = new Wheel();
public void Say()
{
Console.WriteLine("I'm a cal with only one wheel.");
}
public static implicit operator Wheel(Car itemCar)
{
return itemCar._wheel;
}
}
注:implicit 关键字用于声明隐式的用户定义类型转换运算符
class Program
{
static void Main(string[] args)
{
object itemCar = new Car();
Cast(itemCar);
Console.ReadLine();
}
private static void Cast(object obj)
{
Car itemCar = obj as Car;
if (null != itemCar)
{
try
{
Wheel itemWheel = (Wheel)itemCar;
if (null != itemWheel)
{
itemWheel.Say();
}
}
catch (Exception error)
{ }
}
}
}
在上面的main函数中如果将 Cast(itemCar)改成Wheel itemWheel = itemCar as Wheel将会发生第一种错误:编译可
以通过,但是转换会失败。另外如果你将main函数改成如下形式,将会发生第二种错误:编译无法通过。
static void Main(string[] args)
{
Car itemCar = new Car();
Wheel itemWheel = itemCar as Wheel;
itemWheel.Say();
Console.ReadLine();
}
第一种错误发生的原因是:itemCar被定义为object类型,在编译时将itemCar以System.Object类型生成IL代码,运行
时法无法将object类型转换成Wheel类型。第二种错误发生的原因是:Car类型和Wheel类型不兼容,既不符合引用转换的要求
,更不符合装箱转换的要求。在Cast(object obj)函数中如果去掉
Car itemCar = obj as Car 同理也会发生第一种错误。
2、 值数据类型的转换,同时采用is运算符来取消可能因转换引发的异常。
object obj = Value();
int i = ;
if ( obj is int )
i = ( int ) obj;
什么情况下使用as运算法转换
1、 引用转换
A、 隐式引用转换(http://msdn.microsoft.com/zh-cn/library/aa691284(VS.71).aspx);
B、 显示引用转换(http://msdn.microsoft.com/zh-cn/library/aa691291(VS.71).aspx)。
2、 装箱转换(http://msdn.microsoft.com/zh-cn/library/aa691158(VS.71).aspx)。
上面提到在用C风格进行强制类型转换前要采用is运算符进行类型判断,那么is运算符究竟是有什么功能,is运算符和
as运算符有什么区别,我们在使用is运算符时应该注意哪些问题。
is运算符是类型判断运算符,检查对象是否与给定类型兼容,和as运算符一样是安全的,不会发生异常的,与as运算
符不同的是:is运算符不进行类型转换,只返回bool值,表示类型是否兼容。在使用is运算符时注意一下几点:
1、避免冗余。如下面的代码就出现了冗余,实际上is判断是无意义的。
object obj = Value();
if (itemCar is Car)
{
Car itemCar = obj as Car;
}
2、在用C风格进行强制类型转换前尽量要采用is运算符进行类型判断。
object obj = Value();
if (itemCar is Car)
{
Car itemCar = (Car)obj;
}
总之,在能用as运算符的情况下绝不使用C风格的强制转换。因为as运算符比起C风格盲目的强制转换,as运算符更安
全,而且在运行时效率更高。
尽量采用as操作符而不是旧式C风格做强制类型转换的更多相关文章
- EffectiveC#3--选择is或者as操作符而不是做强制类型转换
1.用as运算符进行类型转换.因为比起盲目的强制转换它更安全,而且在运行时效率更高. 安全体现在:as操作符就算是转化一个null的引用时,也会安全的返回一个null而不会像强制转换抛出异常. 2.a ...
- 选择is或者as操作符而不是做强制类型转换
无论何时,正确选择使用as运算符进行类型转换.比盲目的强制类型转换更安全,而且在运行时效率更高. 用as和is进行转换时,并不是对所有用户定义的类型都能完成,只是在运行时类型和目标类型匹配时,转换才能 ...
- 《C#高效编程》读书笔记03-推荐使用is或as操作符而不是强制类型转换
在日常编码中,很多时候都要编写接受object作为参数的方法,接下来是将这些object转型成特定类型,要么类,要么接口.这时我们有两种选择,使用as操作符,或者使用强制类型转换. 正确的做法是,尽可 ...
- C++强制类型转换操作符 static_cast
static_cast是一个强制类型转换操作符.强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast.dynamic_cast.const_cast.reinterpert ...
- C++强制类型转换操作符 dynamic_cast
dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用. >>>>>>>>>>>编译器的RTTI设 ...
- C++强制类型转换操作符 const_cast
const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转 ...
- ubutun:从共享文件夹拷贝文件尽量使用cp命令而不是CTRL+C/V
为了方便,VBOX安装的Ubuntu,并在硬盘上创建了一个与Windows的共享文件夹sharefolder方便在两个系统之间传文件 但是经常发现的问题就是从sharefolder中拷贝文件到ubun ...
- C#的is和as操作符来进行强制类型转换&&值类型的拆箱、装箱
if(o is Employee) { Employee e=(Employee)o; //在if语句剩余的部分中使用e; } Employee e=o as Employee; if(e!=null ...
- ubuntu 使用旧式Gnome风格的菜单
sudo apt-add-repository ppa:diesch/testing sudo apt-get update sudo apt-get install classicmenu-indi ...
随机推荐
- Sprint第二个冲刺(第四天)
一.Sprint 计划会议: 第四次会议总结情况如下展示:昨天完成了美化按钮.增添图片的功能,今天在我们的努力下又完成了查看用户资料和底栏显示功能,由此可见我们团队的小伙伴都很厉害,也很勤奋.从燃尽图 ...
- Oracle语句
分页查询: select rn,last_name,salary from( select rownum rn,last_name,salary from( select last_name,sala ...
- pascal矩阵 分类: 数学 2015-07-31 23:01 3人阅读 评论(0) 收藏
帕斯卡矩阵 1.定义 帕斯卡矩阵:由杨辉三角形表组成的矩阵称为帕斯卡(Pascal)矩阵. 杨辉三角形表是二次项 (x+y)^n 展开后的系数随自然数 n 的增大组成的一个三角形表. 如4 ...
- leetcode 143. Reorder List ----- java
Given a singly linked list L: L0→L1→-→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do thi ...
- mysql数据库从库同步延迟的问题
在从服务器上执行show slave status;可以查看到很多同步的参数,我们需要特别注意的参数如下,希望文章对各位会有所帮助. 在从服务器上执行show slave status;可以查看到很多 ...
- hihoCoder #1040 (判断是否为矩形)
题目大意:给四条线段,问能否构成一个矩形? 题目分析:先判断能否构成四边形,然后选一条边,看另外三条边中是否为一条与他平行,两条垂直. 代码如下: # include<iostream> ...
- 黑马程序员——JAVA基础之内部类,匿名内部类
------- android培训.java培训.期待与您交流! ---------- 内部类 将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类). 内部类访问特点: • 内部 ...
- IAR MSP430如何生成烧写文件
IAR生成430烧写方法有2种, 第一种是:将工程的debug模式切换成release模式,看图片操作. 那个.d43文件就是仿真调试模式的文件. 这里的test.txt文件就是烧写文件了,不要 ...
- c++语法集锦
1.指针的引用 他也是引用,引用是特定内存块的别名 2.变量定义 更准确的说是内存使用约定,并为该约定命名 命名3.指向常变量的指针和常指针 有点拗口,都是指针,但对于所在内存块的使用约定不同.常变量 ...
- XunSearch(讯搜)的使用教程步骤
一.安装编译工具 yum install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2-devel ...