C# 基础知识(磨刀不误砍柴工)

事件
事件的概念与概述
事件:类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的   类称为“发行者”,接收(或处理)事件的类称为“订户”。
特点:
1、发行者确定何时引发事件,订户确定执行何种操作来响应该事件。
2、一个事件可以有多个订户。一个订户可处理来自多个发行者的多个事件。
     没有订户的事件永远不会被调用。
3、事件通常用于通知用户操作,例如,图形用户界面中的按钮单击或菜单选择操作。
4、如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。
5、可以利用事件同步线程。
6、在 .NET Framework 类库中,事件是基于 EventHandler 委托和 EventArgs 基类的。
二、订阅和取消订阅事件
1、使用VisualStudio IDE订阅事件(+=)
1)创建一个空事件处理程序方法。
2)订阅该事件所需要的代码。
2、已编程方式订阅事件(+=)
委托的一系列操作。
3、使用匿名方法订阅事件(+=)
引用代码段
取消订阅(-=)
所有的订户都取消订阅事件后,发行者累中的事件实例将设置为null
发布符合.NET Framework准则的事件
NET Framework 类库中的所有事件均基于 EventHandler 委托
虽然您定义的类中的事件可基于任何有效委托类型(甚至是可返回值的委托),但是,通常建议您使用 EventHandler 让事件基于 .NET Framework 模式
引发派生类中的基类事件
在创建可用作其他类的基类的类时,应考虑如下事实:事件是特殊类型的委托,只可以从声明它们的类中调用。派生类无法直接调用基类中声明的事件。尽管有时需要事件仅由基类引发,但在大多数情形下,应该允许派生类调用基类事件。为此,您可以在包含该事件的基类中创建一个受保护的调用方法。通过调用或重写此调用方法,派生类便可以间接调用该事件。
实现接口事件
为事件编写显式接口实现时,必须编写 add 和 remove 事件访问器。
使用字典存储事件
accessor-declarations 的一种用法是公开很多事件但不为每个事件分配字段,而是使用字典来存储这些事件实例。这只在具有很多事件但您预计大多数事件都不会实现时才有用。
迭代器
迭代器的概念与概述
迭代器:是一种方法、get 访问器或运算符,它通过使用 yield 关键字对数组或集合类执行  自定义迭代。
yield 返回语句会导致源序列中的元素在访问源序列中的下一个元素之前立即返回给调用方。尽管您以方法的形式编写迭代器,但编译器会将其转换为一个实际上是状态机的嵌套类。只要客户端代码中的 foreach 循环继续进行,此类就会跟踪迭代器的位置。
将使用 foreach 语句从客户端代码中调用迭代器。在为类或结构创建迭代器时,您不必实现整个 IEnumerator 接口。当编译器检测到迭代器时,它将自动生成 IEnumerator 或 IEnumerator<(Of <(T>)>) 接口的 Current、MoveNext 和 Dispose 方法。
概述:
 1、迭代器是可以返回相同类型的值的有序序列的一段代码。
 2、迭代器可用作方法、运算符或 get 访问器的代码体。
 3、迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。
 4、可以在类中实现多个迭代器。每个迭代器都必须像任何类成员一样有唯一的名称,并且可以在 foreach 语句中被客户端代码调用
 5、迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<(Of <(T>)>) 或 IEnumerator<(Of <(T>)>)。
 6、迭代器是 LINQ 查询中延迟执行行为的基础。
yield 关键字用于指定返回的一个或多个值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。
迭代器对集合类特别有用,它提供一种简单的方法来迭代复杂的数据结构(如二进制 树)。
使用迭代器
创建迭代器最常用的方法是对 IEnumerable 接口实现 GetEnumerator 方法 
foreach 语句调用 ListClass.GetEnumerator() 并使用返回的枚举数来循环访问值。
还可以使用命名的迭代器以支持通过不同的方式循环访问同一数据集合。
可以带有参数,以便允许客户端控制全部或部分迭代行为
可以在同一个迭代器中使用多个 yield 语句
在 foreach 循环的每次后续迭代(或对 IEnumerator.MoveNext 的直接调用)中,下一个迭代器代码体将从前一个 yield 语句之后开始,并继续下一个语句直至到达迭代器体的结尾或遇到 yield break 语句。
为整数列表创建迭代器
为反省列表创建迭代器
命名空间
一、命名空间
两种方式:
1:.NET Framework 使用命名空间来组织它的众多类,可以用using关键字
2:声明自己的命名空间来控制类名或方法名的范围
命名空间概述:
组织大型代码项目
使用.运算符将他们分隔
Using directive不必为每个类制定命名空间的名称
global命名空间是"根"命名空间:global::System始终引用.Net Framework 命名空间 System
使用命名空间
访问命名空间
大多数 C# 应用程序从一个 using 指令节开始。该节列出应用程序将会频繁使用的命名空间,避免程序员在每次使用其中包含的方法时都要指定完全限定的名称。
命名空间的别名
Using 还可以创建命名空间的别名
Using Co=Company.Project.Nested;
//Co.Class.Method();
使用命名空间来控制范围
完全限定名
命名空间和类型的名称必须唯一。
一般情况下,应使用 :: 来引用命名空间别名或使用 global:: 来引用全局命名空间,并使用 . 来限定类型或成员。
使用命名空间别名限定符
当成员可能被同名的其他实体隐藏时,能够访问全局命名空间中的成员非常有用。
这是可以用完全限定名来解决。Global:System.Console.WriteLine();
使用My命名空间
可以为Null的类型
一、可以为空Null类型
可以为null的类型是System.Nullable<T>结构的实例。可以为 null 的类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。
概述:
可以为 null 的类型具有以下特性:
 1)可以为 null 的类型表示可被赋值为 null 值的值类型变量。无法创建基于引用类型的可以为 null 的类型。(引用类型已支持 null 值。)
 2)语法 T? 是 Nullable<(Of <(T>)>) 的简写,此处的 T 为值类型。这两种形式可以互换。
为可以为 null 的类型赋值的方法与为一般值类型赋值的方法相同,如 int? x = 10; 或 double? d = 4.108;。
 3)如果基础类型的值为 null,请使用 Nullable<(Of <(T>)>)..::.GetValueOrDefault 属性返 回该基础类型所赋的值或默认值,例如 int j = x.GetValueOrDefault();
 4)请使用 HasValue 和 Value 只读属性测试是否为空和检索值,例如 if(x.HasValue) j =  x.Value;
 如果此变量包含值,则 HasValue 属性返回 True;或者,如果此变量的值为空,则返回 False。
 如果已赋值,则 Value 属性返回该值。否则,将引发 System..::.InvalidOperationException。
 可空类型变量的默认值将 HasValue 设置为 false。未定义 Value。
 5)使用 ?? 运算符分配默认值,当前值为空的可以为 null 的类型被赋值给非空类型时将应用该默认值,如 int? x = null; int y = x ?? -1;。
  6)不允许使用嵌套的可以为 null 的类型。将不编译下面一行:Nullable<Nullable<int>> n;
使用可以为null的类型
可以为 null 的类型可以表示基础类型的所有值,另外还可以表示 null 值。可以为 null 的类型可通过下面两种方式中的一种声明:
System.Nullable<T> variable
- 或 -
T? variable
T 是可以为 null 的类型的基础类型。T 可以是包括 struct 在内的任何值类型;但不能是引用类型。
可以为Null的类型示例
任何值类型都可用作可以为null类型的基础。
可以为null类型的成员
HasValue ,Value
显示转换
隐式钻换
从普通类型到可以为Null类型的转换时隐式的。
a = a + b;   // Add b, now a is null.  
??运算符
?? 运算符定义在将可以为 null 的类型分配给非可以为 null 的类型时返回的默认值。

// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;
 
Bool?类型 True    Flase      null
装箱可以为null的类型
基于可以为 null 的类型的对象只在该对象为非空时装箱。如果 HasValue 为 false,则将对象引用赋值为 null,而不进行装箱。
如果对象非空,也就是说,如果 HasValue 为 true,则会发生装箱过程,但只将可以为 null 的对象所基于的基础类型装箱。如果将非空的可以为 null 的值类型装箱,将使值类型本身(而不是包装该值类型的 System..::.Nullable<(Of <(T>)>))装箱。

四、标识可以为nulll的类型
五、从bool?安全地强制类型转化

 

 

 

 
 

 

 

 

 

 

 

posted on 2009-06-03 11:24  孙伊  阅读(312)  评论(1编辑  收藏  举报

导航