接口 类型转换 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

 

 

                                                                                                                                                                                                                                             

posted @ 2014-01-21 11:27  我叫小菜  阅读(651)  评论(0编辑  收藏  举报