21.通过将数组名作为参数传递给System.WriteLine()可以在控制台打印出数组的系统定义类型.
如 float farray = new float[5];
System.WriteLine(farray);
输出: System.Single[]
类似的 对应
类型 |
输出结果 |
double |
System.Double[] |
sbyte |
System.Sbyte[] |
byte |
System.Byte[] |
ushort |
System.Int16[] |
int |
System.Int32[] |
long |
System.Int64[] |
string |
System.String[] |
22. 显示转换 向下转型(数据截取)
显示转换与C,C++中不同,C#中当显示转换时,编译器(开启checked选项)检查到超出转换后类型的值域而发生的溢出则会抛出异常(OverflowException),其余情况发生数据截取或者精度丢失。Float到double, decimal大到无法表示或是无穷和NaN则抛出异常InvalidCastException。
显示引用转化包括:
a. 从对象到任何引用类型
b. 从类类型到S到类类型T,其中S是T的基类
c. 从类类型S到接口类型T,其中S不是密封类,而且没有实现T
d. 从接口类型S到类类型T,其中T不是密封类,而且没有实现S
e. 从接口类型S到接口类型T,其中S不是T的子接口
f. 从元素类型Ts的数组类型S到元素类型Tt的数组类型T的转换,而且这种转换满足条件:
i. S和T只有元素类型不同,而维数相同
ii. Ts和Tt都是引用类型
iii. 存在从Ts到Tt的显示引用转换
iv. 从System.Array到数组类型
v. 从System.Delegate到代表类型
vi. 从System.ICloneable到数组类型或者代表类型
为了确保显示引用转换的正常进行,要求源变量的值必须为null或者他所引用的对象的类型可以被隐式引用转换转换为目标类型。否则显示引用转换失败,抛出InvalidCastException异常。
注意:不论是显示引用转换还是隐式引用转换,只改变引用类型,而不改变引用类型指向的数据值的类型。
23.as操作符,通过引用转换或者装箱转换将一个值显示的转换成指定的引用类型。As操作符不会产生任何异常,如果转换不可以进行,则结果值为null
格式 Expresstion(表达式) as Type(引用类型)
24.checked 和 unchecked操作符,用于整形运算时控制当前环境中的溢出检查,如果溢出则抛出OverflowException异常。
注意:checked和unchecked检查异常,只对之后的表达式检查,而不对之后括号中的函数调用内部进行检查.
25. C#中else与离其最近的if对应,
因此 if(a) if(b)e1; else(c) e2;
等价于 if(a){
if(b)
e1;
else©
e2;
}
25.C#中switch语句中各case后如果不加break或者goto语句,不会像C,C++中那样继续执行下一个case,将会报错。
可以用 goto case 值/default进行跳转
在C,C++中switch-case语句只能对整形或者字符型变量有效,对字符串不可使用,而在C#中可以在switch-case语句中使用字符串常量,且case标签中允许null值。
26.C#在流程控制中多了一个foreach关键字
foreach语句表示收集一个集合中的各元素,并针对各个元素执行内嵌语句。
语句格式:
foreach(类型 + 标识符(循环变量) + in(关键字) + 表达式) 嵌套语句
每执行一次内嵌语句,循环变量就依次取集合中的一个元素带入其中。
此处的循环变量是一个只读型局部变量,如果试图改变它的值或将它作为一个ref或者out类型的参数传递,都会引发编译错误。
foreach中表达式是一个集合类型,如果该集合的元素类型与循环变量类型不一致,则必须有一个显示定义的从集合中的元素类型到循环变量元素类型的显示转换。
在C#中集合类型的语法定义:
(1) 该类型必须支持一个形为GetEnumerator()的公有的非静态方法,该方法的返回类型为结构,类或者接口。
(2) 形为GetEnumerator()的方法返回的结构,类或者接口应当包含一个公有的非静态方法MoveNext(),该方法的返回类型为布尔值
(3) 形为GetEnumerator()的方法返回的结构,类或者接口应当包含一个公有的非静态的属性Current(其类型称为集合的元素类型),该属性可以读出。
[数组支持foreach]
27.C#没有独立的预处理器,C# 中的预处理指令仅仅用来和C,C++保持一致,而并不是编译器开始编译代码之前的一个单独的处理步骤,它是作为词法分析的一部分来执行的。
#define #undef应该放在任何非预处理指令之前.
C#中预处理指令如果出现在其他输入输出元素的中间就不会被执行。
如此程序试图在Debug时显示 He is a doctor,否则显示He is a teacher
using System;
class myprog{
static void main(){
Console.WriteLine(@”He is a
#if Debug
doctor
#else
teacher
#endif
“);
}
}
结果输出却为
He is a
#if Debug
doctor
#else
teacher
#else
28.C#与C++异常处理的不同之处
1).在C#中,所有异常都表现为一个类的实例,这个类继承自System.Exception类。而在C++中,任何类型的任何值都可以表示异常。
2).C#中一个终结块里的终结代码既可以在正常情况下执行,也可以在异常情况下执行,而在C++中,不复制代码是难以做到的。
3).在C#中,系统级的异常,如溢出,除数为0等,由于有定义完好的异常类因而可以等同于应用程序及错误条件。
29.异常相关
引发异常的条件:
1).throw语句无条件,即时地抛出异常。
2).C#语句和表达式执行过程中激发了某个异常的条件,使得操作无法正常结束,从而引发异常。
throw语句抛出异常: throw expresstion()
30.C#类定义之后无分号