C# 基本概念8

来源:互联网 发布:腾讯社交广告优化师 编辑:程序博客网 时间:2024/06/03 19:14
委托和事件

委托是C# 语言中一种引用方法的类型,和C++ 中处理函数指针的情
况比较相似。不但可以向委托实例注册方法列表,而且还可以通
过委托实例来调用方法列表中的方法。事件是一种特殊的委托,
它包含两个参数:指示事件源的“对象源”参数和封装事件的其
他任何相关信息的“e” 参数。
  声明委托;
  委托实例化;
  委托调用;
  声明事件;
  注册事件和移除事件;
  调用事件。


委托

熟悉C++ 中函数指针的读者可能比较容易理解委托。委托(
delegate )是一种数据结构,它是用来处理类似于C++ 中
函数指针的情况,即委托能够引用静态方法或引用类实
例及其实例方法。特别地,委托是完全面向对象的,同
时也封装了对象实例和方法。
所有委托类型的基类是System.Delegate 类。System.Delegate
类本身不是委托类型,而且不允许显式地直接从该来派
生新的类型。委托实例封装了一个调用列表,该列表包
含了一个或多个方法,每个方法称为一个可调用实体。


委托声明

委托类型的声明将创建一个协定,该协定指定一个或多个方法的
签名。委托是委托类型的实例,它可以引用静态方法或者实例
方法。声明委托需要使用delegate 关键字,语法如下。
delegate-modifiers delegate return-type identifier
delegate-modifiers 表示委托的修饰符(可选),它包括new 、
public 、protected 、internal 和private 共5 个关键字。其中,
public 、protected 、internal 和private 修饰符控制委托的可访问
性。它们的意义具体说明如下。
 public 修饰符,表示该委托是公开的,访问不受限制。
 protected 修饰符,表示该委托只能是本身委托访问。
 internal 修饰符,表示该委托只能是在当前应用程序中访问。
 private 修饰符,表示该委托只能是本身访问。


创建向委托注册方法

一旦声明一个委托之后,那么就指定了该委托方法列表中的
方法签名,包括方法列表中的方法的返回类型和方法参
数。如果一个方法能够注册到某一个委托中,那个该方
法的签名必须与该委托的所指定的签名完全匹配。匹配
规则如下。
  方法的返回类型必须和委托的返回类型相同。
  方法的方法参数必须和委托的方法参数相同,参数的具
体名称可以不相同。


委托实例化

委托实例化可以创建委托类型的实例,并向该实例注册方法
列表。委托类型的实例的方法列表可以为静态方法、实
例方法或者另外一个委托实例。
注意:委托实例化,它把静态方法、实例方法或者另外一个
委托的名称作为该实例的方法参数进行传递。


委托的方法列表

一个委托实例都必须包含其方法列表,方法列表可以包含一
个或多个方法。委托实例除了在其实例化时注册方法之
外,还可以通过“+” 或“+=” 运算符向该实例的方法列表
中的注册方法,通过“-” 或“-=” 运算符向该实例的方法
列表中的移除方法


委托调用

一个委托实例的方法列表,又称为该委托实例的调用列表。
一个调用列表可能包含一个或多个方法。如果一个调用
列表包含多个方法时,当该委托实例被调用时,它将按
照调用列表中方法的注册顺序依次调用每一个方法。


事件

事件(event )是一种使对象或类能够提供通知的成员。客
户端可以通过提供事件处理程序为相应的事件添加可执
行代码。客户端可以实现为事件定义一些操作或方法,
当事件发生时,将调用该事件事先定义的操作或方法。


声明事件

事件其实是一种特殊类型的委托,它包含两个参数:指示事
件源的“对象源”参数和封装事件的其他任何相关信息
的“e” 参数。其中,“e” 参数的类型为System.EventArgs
类型或从System.EventArgs 类派生的类型。声明事件一般
包括以下两个步骤。
(1 )声明事件的委托。
(2 )声明事件本身。


注册事件

一个事件一旦声明之后,该事件的默认值为null 。如果希望
该事件执行事先指定的操作,则首先向该事件注册方法
列表(即委托的调用列表)。注册事件可以使用“+=” 运
算符。


移除事件

除了注册事件之外,还可以移除事件。移除事件使用“-=”
运算符。


调用事件

声明一个事件之后,如果没有向该事件注册方法,那么该事
件的值为空(null )。因此,在调用事件时,往往需要检
查该事件是否为空。


异常处理

异常是程序执行时遇到的任何错误情况或意外行为。应用程
序必须能够统一处理在执行期间发生的错误。.NET
Framework 公共语言运行库提供了一个模型,以统一的
方式通知程序发生的错误。
  异常概述;
 try 语句;
 System.Exception 类;
 .NET Framework 常用异常类;
  创建自定义异常类。


异常概述

和C++ 程序语言一样,C# 程序语言也存在异常处理机制。
C# 程序语言中的异常用于处理系统级和应用程序级的错
误状态,它是一种结构化的、统一的和类型安全的处理
机制。


导致异常的原因

在应用程序运行时,发生异常的原因是多种多样的,如除数
为0 、堆栈溢出等。导致异常的原因可以归纳为以下2 大
类。
  在执行语句和表达式(C# 语言)的过程中,有时会出现
一些例外情况,从而使得某些操作无法正常完成,此时
就会引发一个异常。
  应用程序使用throw 语句特意产生一个异常,此时将引发
一个异常。


try 语句

try 语句可以用来捕捉在代码块的执行期间发生的各种异常
。它可以包含try 块、catch 块和finally 块,具体说明如下

 try 块,一般包含有可能发生异常的代码。
 catch 块,包含出现异常时需要执行的响应代码。
 finally 块,包含出现异常时一定执行的代码,如资源清理
等操作。


异常处理

异常是由try 语句处理的。当发生异常时,系统将搜索与当
前try 块相关的最近的、可以处理该异常的catch 块,然后
由该catch 块处理该异常。如果与当前try 块相关的所有
catch 块都不能处理该异常,则沿着堆栈向上搜索封闭该
异常代码的try 块及其相关联的catch 块,如果找到,则由
该catch 块处理该异常。如果还没有找到catch 块,则重复
上述过程,直到找到catch 块。如果到达调用堆栈顶部仍
然没有找到处理该异常的catch 块,则由默认的异常处理
程序处理该异常,然后应用程序终止。


System.Exception 类

System.Exception 类表示在应用程序执行期间发生的错误,它是
.NET Framework 中所有异常的基类型。当系统或应用程序
发生错误时,将通过引发包含错误信息的异常来报告错误。
一旦异常发生后,将由该应用程序或默认异常处理程序(如
System.Exception 类)来处理异常。
System.Exception 类包含描述错误的可读文本。当异常发生时,
应用程序的运行库(如.NET Framework )将产生消息(保
存在Exception 类的实例的Message 属性中)通知用户错误的
性质并提供解决该问题的操作建议。Exception 类包括以下两
类异常。
  从SystemException 派生的预定义公共语言运行库异常类。
  从ApplicationException 派生的用户定义的应用程序异常类。


常用异常类

.NET Framework 提供了10 个常用异常类,如处理空(null )引用的
System.NullReferenceException 类、处理数组索引小于0 或超过其下标
的System.IndexOutOfRangeException 类等。这些常用异常类及其说明
如下所示。
类  描述
System.NullReferenceException  如果使用null引用,引发此异常。
System.IndexOutOfRangeException  如果使用小于零或超出数组界限的下标访问数组时,引发该异常。
System.InvalidCastException  如果显式转换失败时,就会引发此异常。
System.DivideByZeroException  当除数为0时,引发该异常。
System.StackOverflowException  当堆栈溢出(如无限递归)时,引发该异常。
System.OverflowException  在checked上下文中的算术运算溢出时,引发该异常。
System.OutOfMemoryException  在通过new操作分配内存失败时,引发该异常。
System.ArithmeticException  在算术运算期间发生错误时,引发该异常。
System.TypeInitializationException  静态构造函数引发异常,且没有可以捕捉到它的catch子句时,引发该异
常。
System.ArrayTypeMismatchException  如果被存储的元素的实际类型与数组的元素类型不兼容时,引发此异常。


泛型

泛型(Generic )是具有占位符(类型参数)的类、结构、
接口和方法,这些占位符是类、结构、接口和方法所存
储或使用的一个或多个类型的占位符。泛型集合类可以
将类型参数用作它所存储的对象的类型的占位符;类型
参数作为其字段的类型和其方法的参数类型出现。泛型
方法可以将其类型参数用作其返回值的类型或者其形参
的类型之一。本章将讲解C# 语言中的泛型。
  泛型概述;
  泛型方法;
  创建泛型列表
  创建泛型堆栈。


泛型概述

使用过C++ 模板的读者可能熟悉泛型(Generic )这一概念
。C# 中的泛型能够将类型作为参数来传递,即在创建类
型时,事先使用一个特定的符号(如T 等)代替实际的类
型,在创建该类型的实例时,才指定T 的实际类型。
泛型可以让类、结构、接口、委托和方法按它们存储和操作
的数据的类型进行参数化。泛型能提供更强的编译时类
型检查,减少数据类型之间的显式转换,以及装箱操作
和运行时的类型检查。
使用泛型类型可以最大限度地重用代码、保护类型的安全以
及提高性能。泛型最常见的用途是创建集合类。.NET
Framework 类库在System.Collections.Generic 命名空间中
包含多个新的泛型集合类,如List<T> 、Stack<T> 、
Queue<T> 等。当然,开发人员也可以创建自定义泛型类
型。


泛型类声明

泛型类声明也是一种类的声明,因此,泛型类声明也遵循类
声明的规则。一个泛型类一般至少包含一个类型形参。当创
建该泛型类的实例时,需要指
定该类型形参的具体类型。


类型形参

类型形参放置在类名后,并在“<” 和“>” 分隔符中指定。类
型形参仅仅是一个简单标识符,是将来提供的类型的形
式占位符。换句话说,T 类型形参只起占位符的作用,直
到在使用时才为其指定了实际类型。
每一个类型形参所代表的实际类型由其所在实例创建时指定
。特别地,该实例将存储类型形参的数据而不进行数据
类型转换。


类型形参的约束

通常地,类型形参的类型可以指定为任何类型。然而,一些
类型形参需要指定一定种类的类型,如结构、类等。为
了实现该功能,就需要限制类型形参的类型,这种限制
被称为约束。即在定义泛型类时,可以限制在实例化类
时用于类型参数的类型种类。如果尝试使用某个约束所
不允许的类型来实例化类,则会产生编译时错误。


泛型类的成员

泛型类的所有成员都可以直接使用其所属类的类型形参。在
运行时,类型形参都被替换为相应的实际类型(该类型
在创建类的实例时指定)。


泛型类的静态字段

在泛型类中,静态字段的共享方法比较特殊,即只有在具有
相同类型形参的类型的实例才能够共享同一个静态字段
的值。


泛型方法

泛型方法(Generic Method )是使用类型参数声明的方法,
它可以声明在类、结构或接口中,而这些类、结构或接
口本身可以是泛型或非泛型的。如果这些类、结构或接
口也是泛型类型时,那么在这些方法内既可以引用该泛
型方法的类型形参,也可以使用这些类、结构或接口的
类型形参。


声明泛型方法

和普通方法相比,除了普通的参数之外,泛型方法还必须包
含类型形参,即泛型方法是指在声明中包含类型形参的
方法。


调用泛型方法

泛型方法调用可以显式指定类型实参列表,或者可以省略类
型实参列表并依赖类型推断确定类型实参。通常地,调
用泛型方法和调用普通方法一样,但需要为类型形参提
供相应的类型实参列表。


通过委托调用泛型方法

还可以通过委托来
调用泛型方法。


虚泛型方法

和普通方法一样,泛型方法也存在虚泛型方法,它也可以使
用abstract 、virtual 和override 修饰符进行声明。
原创粉丝点击