接口 类型转换 try-catch(学习笔记)
(抽象类,接口)内容已经在前面的博客有记载http://www.cnblogs.com/tobecabbage/p/3460984.html http://www.cnblogs.com/tobecabbage/p/3468115.html
- 转换的说明
-》隐式类型转换:正常的值类型的隐式转换,里氏转换原则,装箱
double dNum=123;
-》强制类型转换:正常的值类型的强制转换,里氏转换原则,拆箱
int num=(int)123.456;
-》类型转型
int num=Convert.ToInt32("123");
计算机只认识0和1,所以用二进制表示(两个位bit),8个bit表示一个字节
int32 4个字节 0000 0000 0000 0000 0000 0000 0000 0000
因这二进制不便于阅读,所以计算机用16进制描述数据。
8位一个字节
0000 0001 1
0000 0010 2
0000 0011 3
0000 0100 4
0000 0101 5
0000 0110 6
0000 0111 7
....
1111 1111 0-255共256个数字 恰好是16的平方
二进制 16进制
1000 8
1001 9
1010 a
1011 b
1100 c
1101 d
1110 e
1111 f
0001 0000 10
单步调试到Main方法的最后一行,查看变量内存地址中数据
double类型的数据可以除以0,得到正无穷大
double bd=90.0000; Console.WriteLine(bd/0.0000000000);//结果为正无穷大
里氏转换见前面的博客已有记载,简单解释概括为:子类的对象new sub()分配的内存空间地址偏移量比父类的对象New base()要大。所以一个父类的引用变量指向一个子类的对象是可以的,只是访问不到子类的数据而已(若想访问到子类对象的数据,需要重写父类的方法)。而一个父类的对象地址偏移量小,却用一个子类的引用变量指向,这就意味这可以用这个子类的引用变量反问到子类的数据,可是该子类引用变量指向的确实父类的对象,内存空间里根本没有子类的数据。这与子类引用变量能访问到子类的数据相矛盾()。
里氏转换 base b= new sub(); sub s=(sub)b;因为b本来指向的就是一个sub()对象,里面存有子类的数据,所以sub类型引用变量s能访问到sub对象的数据。转换陈功。里氏转换的存在的目的是为了实现多肽。
装箱拆箱前面博客已有记
- 异常是程序中运行时错误,它违反了一个系统的约束或应用程序约束,或出现了正常操作时未预料的情形。
Convert.ToInt32("123abc");//格式不正确
Convert.ToInt32("12345678901234567890");//对于int32太大或太小
写程序
-》遇到程序怎么样让程序不挂起
-》怎样抛出异常
try语句
如果程序没有提供处理异常的代码,系统会挂起这个程序。
♢try语句用来指明被正异常保护的代码块,并提供代码以处理异常。
♢catch字句部分含有一个或多个catch字句。,这些都是处理异常的代码块,它们也称为是异常的处理程序。
♢finally块含有在所有情况下都要被执行的代码,无论有没有异常发生。
catch字句部分与finally字句部分必须至少有一个,如果两个都有,finally必须放在最后,即catch字句的后面
处理异常的代码
satic void Main(){
int x=10;
try{
int y=0;
x/y;
}
catch{
...//处理异常的代码
Console.WriteLine("Handling all exceptions - Keeping on Runing");
}
}
这段代码产生以下消息。注意,除了输出消息,没有异常已经发生的迹象。
Handling all exceptions-Keeping on Runing
异常类
有许多不同类型的异常可以在程序中发生,BCL定义了许多类,每一个类代表了一个指定的异常类型。当一个异常发生时,CLR:
♢创建该类型的异常对象;
♢寻找适当的catch字句以处理它。
所有的异常都从根本上派生自System.Exception类。
System.Exception:所以异常类的基类
-》SystemException:所有预定义系统异常的基类。IndexOfRangeException NullReference IOException
-》ApplicationException:所有致命的、应用程序定义的异常的基类。
异常对象含有只读属性,带有导致该异常的信息。
属性 类型 描述
Message string 这个属性含有解释异常的原因的消息
StackTrace string 这个属性含有描述异常发生在何处的信息
InnerException Exception 如果当前异常是由另一个异常引起的,这个异常包含前一个异常的引用
HelpLink string 这个属性可以被应用程序定义的异常设置,为异常原因信息提供URN或URL
Source string 如果没有被应用程序定义的异常设定,那么这个属性含有异常起源所在的程序集的名称。
Catch字句的三种形式
catch{
Statements 一般catch字句,在catch关键字之后没有参数列表,匹配try块中引起的任何类型的异常。
}
catch(ExceptionType){
Statements 特定catch字句 带有异常类的名称作为参数 匹配任何该类型的异常
}
catch(ExceptionType Exception){
Statements 带对象的的特定Catch字句,在异常类名称之后包括一个标识符,该标识符在catch字句块中相当于一个本地变量,并被称为异常变量
} 异常变量应用异常对象,并能用于访问该变量的信息
一般catch字句能接受任何异常,但不能确定引发异常的类型。
特定catch字句形式把一个异常类的名作为参数,它匹配该指定类或派生自它的异常类的异常。
带对象的特定catch字句提供最多的关于异常的信息。它匹配指定类的异常,或派生自它的异常类的异常。它还给出一个异常实例,称为异常变量,它是一个对CLR创建的异常对象的引用。
使用特定Catch字句的示例
int x=0;
try{
int y=0;
x/y;
}
catch(DivideByException){
...
Console.WritelLine("Handling an exception");
}
int x=0;
try{
int y=0;
x/y;
}
catch(DividedByException e){
Console.WriteLine("Messsage:{0},e.Message);
Console.WriteLine("Source:{0},e.Source);
Console.WriteLine("Stack:{0},e.StackTrace);
}
Catch 字句块目的是允许你以一种优雅的方式处理异常。
catch字句块可以包含多个catch字句,特定catch 字句允许多于一个,一般catch字句只允许一个。
catch字句的排序有两个重要的规则
♢特定catch字句必须以一种顺序排序,最明确的异常类型第一,直到最普通的类型,例如,如果声明一个派生自NullReferenceException的异常类,那么派生自异常类型的Catch子句应该被列在NullReferenceException的catch字句之前。
♢如果有一个catch子句,它必须是最后一个,它必须在所有特定的catch子句之后,使用一般catch子句一般是不好的,应该尽可能使用特定的catch子句。一般catch子句通过让程序继续执行隐藏错误。
- 抛出异常
func1(){func2();}
func2(){func3();}
func3(){func4();}
如果func4()里面出现异常,首先在func4()里查找是否有匹配的异常处理的代码,若没有,继续往上抛异常,在func3()里面找匹配的代码块...若一直没找找到,就抛给Main()方法,若还是找不到匹配的异常处理代码,继续抛给CLR,继续抛给操作系统。
class Program { static void Main(string[] args) { Myclass MCls = new Myclass(); try { MCls.A(); } catch (System.DivideByZeroException) { Console.WriteLine("catch cause in main()"); } finally { Console.WriteLine("finally cause in main()"); } Console.WriteLine("After try statement in Main."); Console.WriteLine(" ---keep running"); Console.ReadKey(); } } class Myclass { public void A() { try { B(); } catch (System.NullReferenceException) { Console.WriteLine("catch clause in A()"); } finally { Console.WriteLine("finally clause in A()"); } } void B() { int x = 0, y = 0; try { x/=y; } catch (System.IndexOutOfRangeException) { Console.WriteLine("catch clause in B()"); } finally { Console.WriteLine("finally clause in B()"); } } }
程序运行结果
图解:
抛出异常
throw new Exception();
- 异常的性能问题
static void Main(string[] args) { Stopwatch s = new Stopwatch(); s.Start(); int sum = 0; for (int i = 0; i < 100;i++ ) { sum += i; } s.Stop(); Console.WriteLine(s.Elapsed);//结果为00:00:00:0.0000079 Console.ReadKey(); }
static void Main(string[] args) { Stopwatch s = new Stopwatch(); s.Start(); int sum = 0; for (int i = 0; i < 100;i++ ) { try { throw new Exception("错误"); } catch (System.Exception ex) { } } s.Stop(); Console.WriteLine(s.Elapsed);//结果为00:00:01:2128577 Console.ReadKey(); }
从以上代码中可以看出,try{}catch(){}会导致运行速度非常慢。所以建议慎用try-catch字句,尽可能用if-esle。若是涉及到访问本地文件,没有权限,或是访问数据库,网忽然断掉的异常采用try-catch