<C#高级编程>第5章笔记
第5章 运算符和强制类型转换
C#中可用的运算符关键字:sizeof(只用于不安全代码)、is、typeof、as、checked、unchecked
间接寻址运算符:*、->、&(只用于不安全代码)、[]
checked:将检查代码段中是否溢出,当发生溢出时抛出异常
unchecked:不检查代码段溢出,若发生溢出则丢失数据(如byte值为256时因溢出而变为0)。
默认值,只有在标记为checked的大代码块中才有必要使用unchecked。
is 运算符:检查对象是否与特定类型相同或是其子类型(类似于Java中的instanceof)
as 运算符:引用类型的显式类型转换,若类型不兼容将返回null。
sizeof 运算符:确定堆栈中值类型所需要的长度(字节)。
typeof 运算符:用于返回一个表示特定类型的Type对象,反射中使用。(类似于Java中调用对象的getClass()方法)
装箱与拆箱
装箱:值类型隐式转换为引用类型
拆箱:引用类型显式转换为值类型(cast),若类型不对或超过范围将抛出异常。
相等性比较
System.Object 类中提供了ReferenceEquals()、virtual Equals()、static Equals()三个方法,加上==运算符一共有四种比较方式。
ReferenceEquals():静态方法,测试两个引用是否执行类的同一个实例。不过它认为null等于null。
不能用于值类型比较(因为总是会自动装箱,导致比较的一定不是同一个引用,因此总是返回false)。
virtual Equals():形如Java中的equals()。如果要作为字典中的键就需要重写该方法以比较值。
值类型也是使用该方法进行比较,因为System.ValueType重载了该方法。
结构的默认比较是比较其所有字段的值是否都相同。
static Equals():静态方法,带有两个参数,对其进行比较。功能与虚拟的Equals()方法相同,但是静态方法可以处理一个是null的情况。如果都不为null,将会调用虚拟的Equals方法,因此重写virtual Equals()也相当于重写静态方法。
== 运算符:大多数情况下表示比较引用(与Java中的相同)。但是有时会被重载,如System.String类就是比较字符串的内容。
运算符重载
与C++中的相似,语法是:
public static 返回类型 operator 一元运算符 (参数类型 arg)
public static 返回类型 operator 二元运算符 (左参数类型 leftArg, 右参数类型 righArg)
与C++不同的是,C#不能重载=运算符。
但如果重载了+运算符,就会自动调用+运算符的重载来执行+=操作。其他*=运算符也遵循此规则。
对于比较运算符,C#中有3对:① == 和 !=,② > 和 < ,③ >= 和 <=。必须成对重载。
即若重载了>,就必须重载<,否则会出现编译错误。它们的返回值总是bool类型。
另外,重载==和!=时,还必须重载Equals()和GetHashCode()方法,否则会产生编译警告。因为Equals()应与==相同逻辑。
为避免出现空指针异常,不要在比较运算符中调用Equals()方法。
可以重载的运算符包括所有的算术运算符、位运算符(其中true和false必须成对重载)、比较运算符(必须成对重载)。
赋值运算符不能显式重载,在单个运算符被重写时会被隐式重写。
索引运算符([])和数据类型转换运算符(())不能直接重载
用户定义的数据类型转换
类似于C++中的自定义类型转换,但是是静态的:
public static implicit operator 目标类型(自身类型 arg)
类之间的转换时,两个类不应有互相的派生关系。
基类与派生类之间的转换是由编译器提供的(实际上并没有进行任何转换,仅仅是复制了引用)。
值类型和结构的转换总是与object之间的转换,除了复制引用之外还必须复制一些值。