const和readonly、as和is、out和ref
readonly
readonly 关键字与 const 关键字不同。const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段为编译时常数,而 readonly 字段可用于运行时常数
as
as:用于检查在兼容的引用类型之间执行某些类型的转换。
Employee myEmployee = myObject as Employee;
if (myEmployee != null) { }
在这段代码中,CLR核实myObject是否兼容于Employee类型;如果是,as会返回对同一个对象的一个非null 的引用。如果myObject不兼容于Employee类型,as运算符会返回null。
as运算符的工作方式与强制类型转换一样,只是它永远不会抛出一个异常。相反,如果对象不能转换,结果就是null。所以,正确的做法是检查最终生成的一引用是否为null。如果企图直接使用最终生成的引用,会抛出一个System.NullReferenceException异常。以下代码对此进行了演示:
Object o = new Object(); 新建一个Object对象。
Employee e = o as Employee; 将o转型为一个Employee
e.ToString(); 访问e会抛出一个NullReferenceException异常
as运算符只执行引用转换和装箱转换。as运算符无法执行其它转换,如果用户定义的转换,这类转换应使用强制转换表达式来执行。
Is
Is:检查对象是否与给定的类型兼容。
例如,下面的代码可以确定MyObject类型的一个实例,或者对象是否从MyObject派生的一个类型:
if(obj is MyObject){}
如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true。如果已知表达式始终是true或始终是false,则is关键字将导致编译时警告,但是通常在运行时才计算类型兼容性。
注意:is运行符不能重载,is运行符只考虑引用转换、装箱转换和取消装箱转换。不考虑其它转换,如果用户定义转换。在Is运算符的左侧不允许使用匿名方法。lambda表达式属于例外。
Object myObject = new Object();
Boolean b1 = (myObject is Object); true.
Boolean b2 = (myObject is Employee); false.
如果对象引用是null,is运算符总是返回false,因为没有可检查其类型的对象。
is运算符通常像下面这样使用:
1 if (myObject is Employee) 2 { 3 Employee myEmployee = (Employee)myObject; 4 }
Out
out 关键字会导致参数通过引用来传递。 这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。 若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。
程序实例:
1 class OutExample 2 { 3 static void Method(out int i) 4 { 5 i = 44; 6 } 7 static void Main() 8 { 9 int value; 10 Method(out value); 11 // value is now 44 12 } 13 }
out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值,样的 属性不是变量,因此不能作为 out 参数传递.
ref
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
- 若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
- 传递到 ref 参数的参数必须最先初始化。这与 out 不同,out 的参数在传递之前不需要显式初始化。
- 属性不是变量,因此不能作为 ref 参数传递。
- 尽管 ref 和 out 在运行时的处理方式不同,但它们在编译时的处理方式是相同的。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的。如果尝试这么做,将导致不能编译该代码。
- 如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载。
程序实例:
1 class RefExample 2 { 3 static void Method(ref int i) 4 { 5 i = 44; 6 } 7 static void Main() 8 { 9 int val = 0; 10 11 Method(ref val); 12 13 // val is now 44 14 } 15 }