运算符和强制类型转换//运行下面这段代码,就会抛出异常
运算符和强制类型转换
byte b=255;
运算符和强制类型转换
checked
Console.WriteLine(b.ToString());

1.2 is运算符
is运算符可以检查对象是否与特定的类型兼容。
运算符和强制类型转换int i = 10;
运算符和强制类型转换
if(i is object)
}

1.3 as运算符
as运算符用于执行引用类型的显示类型转换。如果转换类型与指定的类型兼容,转换成功;如果不兼容,返回null
运算符和强制类型转换object o1 = "some string";
运算符和强制类型转换
object o2 = 5;
运算符和强制类型转换
string s1 = o1 as string;  //s1="some string"
运算符和强制类型转换
string s2 = o2 as string;  //s2=null 

1.4 sizeof运算符
使用sizeof运算符可以确定堆栈中值类型需要的长度(单位字节):注意只能在不安全的代码中使用sizeof
例如:sizeof(int)

1.5 type运算符
返回一个表示特定类型的Type对象。
例如:typeof(string)返回表示System.String类型的Type对象。在使用反射动态查找对象信息时,这个运算很有效。

二、类型转换

2.1 隐式转换
只能从较小的整数类型隐式转换为较大的整数类型,不能从较大的整数类型隐式地转换为较小地整数类型。
无符号的变量可以转换为有符号的变量,只要无符号的变量值的大小在有符号的变量的范围之内即可。
例如:
运算符和强制类型转换byte v1 = 10;
运算符和强制类型转换
byte v2 = 23;
运算符和强制类型转换
long total;
运算符和强制类型转换total 
= v1 + v2;//v1、v2均隐式转换为long类型

2.2显示转换
在不能隐式转换的时候,可以显示执行这些转换。格式如下:
运算符和强制类型转换long val = 3000000000;
运算符和强制类型转换
int i = (int)val;//编译不会报错
所有的显示数据类型转换都可能不安全,在应用程序中应包含处理可能失败的数据类型转换的代码。例如:try/catch等
显示转换有一些限制,值类型只能在数字、char类型和enum类型之间转换。不能直接把Boolean数据类型转换为其他类型,也不能把其他类型转换为Boolean数据类型。

2.3装箱和取消装箱
装箱可以把值类型转换成引用类型(boxing),取消装箱可以把引用类型转换成值类型(unboxing)
运算符和强制类型转换int i = 20;
运算符和强制类型转换
运算符和强制类型转换
object o = i;  //boxing
运算符和强制类型转换

运算符和强制类型转换
int j = (int)o; //unboxing

三、对象的相等比较

3.1 引用类型的相等比较
有四种方法:
1)ReferenceEquals()方法
      ReferenceEquals()方法是一个静态方法,不能重写,只能使用System.object实现。如果提供的两个引用指向同一个对象实例,ReferenceEquals()方法
返回true,否则返回false。但是该方法认为null等于null。
运算符和强制类型转换SomeClass x,y;
运算符和强制类型转换
= new SomeClass();
运算符和强制类型转换
= new SomeClass();
运算符和强制类型转换
bool B1 = ReferenceEquals(null,null);// return true;
运算符和强制类型转换
bool B2 = ReferenceEquals(null,x);// return false;
运算符和强制类型转换
bool B3 = ReferenceEquals(x,y);// return false because x and y point to different objects;

2)虚拟的Equals()方法
      Equals()方法是虚拟的,所以可以在自己的类中重写。
3)静态的Equals()方法
      静态的Equals()方法和虚拟的Equals()方法作用相同,区别是静态版本带有两个参数。静态方法可以处理两个对象中有一个是null的情况。
4)比较运算符==
      ==可以看作是严格值比较和严格引用比较之间的中间选项,使用时最好重写==运算符

3.2 值类型的相等比较
      值类型的相等比较与引用类型的相等比较采用相同的规则,最大的区别就是值类型需要装箱,才能执行上面介绍的四种方法。

四、运算符重载

 4.1 算术运算符重载    例如:
运算符和强制类型转换//定义结构Vector
运算符和强制类型转换
struct Vector
)
注意:C#不允许重载=运算符,但如果重载+运算符,编译器就会自动使用+运算符的重载来执行+=运算符的操作。-=、&=、*=、/=也遵循此规则

4.2 比较运算符重载
1)C#要求成对重载比较运算符(==和!=、>和<、>=和<=共3对),如果不成对重载,编译就会出错。
2)必须返回bool类型的值。
注意:重载==和!=时,还应重载System.object的Equals()方法和GetHashCode()方法,否则产生一个编译警告。因为Equals()方法执行与==相同的相等逻辑。
除此之外,比较运算符重载跟算术运算符的重载没有区别。

五、用户定义的数据类型转换

用户定义的数据类型转换和预定义的数据类型转换一样,也分隐式转换和显示转换两种。
如果知道无论在源变量中存储什么值,数据类型转换总是安全的,就可以用隐式转换;
如果某些数据值可能会出错,就应该把数据类型转换定义为显示的。
定义数据类型的转换类似于运算符重载:
运算符和强制类型转换public static implicit operator float(Currency value)
}
执行用户类型转换的完整示例:
运算符和强制类型转换struct Currency
 

5.1 类之间的数据类型转换
     两个限制:
     1)如果某个类直接或间接继承了另一个类,就不能在这两个类之间进行数据类型转换。
     2)数据类型转换必须在源或者目标数据类型定义的内部定义。

5.2 基类和派生类之间的数据转换       
运算符和强制类型转换//类MyDerived派生于类MyBase
运算符和强制类型转换
  MyDerived derivedObject = new MyDerived();
运算符和强制类型转换  MyBase baseCopy 
= derivedObject;//隐式转换
运算符和强制类型转换

运算符和强制类型转换  MyBase baseObject 
= new MyBase();
运算符和强制类型转换  MyDerived derivedCopy 
= (Myderived)baseObject;//抛出异常
运算符和强制类型转换

5.3 装箱和取消装箱数据类型转换
      值类型到object的转换是隐式转换 ,即装箱     
运算符和强制类型转换Curency banlance = new Currency(40,10);
运算符和强制类型转换
object baseCopy = banlance;//隐式转换
     object到值类型的转换是显示转换,即取消装箱
运算符和强制类型转换object derivedObject = new Currency(40,10);
运算符和强制类型转换
object baseObject = new object();
运算符和强制类型转换Currency derivedCopy1 
= (Currency)derivedObject;//OK
运算符和强制类型转换
Currency derivedCopy2 = (Currency)baseObject;//抛出异常

5.4 多重数据类型转换
     
运算符和强制类型转换Currency balance = new Currency(40,10);
运算符和强制类型转换
long amount = (long)balance;//Currency->float->long
运算符和强制类型转换
double amountD = balance;//Currency->float->double

相关文章: