C#复习总结4
2014-12-14 16:05
176 查看
第十三章 委托
什么是委托
委托就是函数的指针。
其和类相似,其实就是用户自定义的引用类型。
委托是包含有序方法列表的对象,这些方法具有相同的签名和返回类型。
MyDel delvar = new MyDel(myInstObj.mym1); < == > MyDel delvar = myInstObj.mym1; //两者之间存成隐式转换。
委托 中还存在给委托赋值,这样会重新指向,组合委托等等。
委托可以添加方法也可以移除方法。 运算符: += -=
调用委托就和调用函数是一样的。
匿名方法:就是没有了 具体的的实例化后的方法名,只有函数体。
注意作用域的范围:
利用正则表达式,可以简化 委托。
代码如下:
delegate
void PrintFunction();//定义一个没有返回值和参数的委托类型
delegate
void MyDel(ref
int x);//引用参数
class Test
{
public
void Print1()
{
Console.WriteLine("Print1 --- instance");
}
public
static
void Print2()
{
Console.WriteLine("Print2 ----- static");
}
public
void ADD2(ref
int x)
{
x += 2;
}
public
void ADD3(ref
int x)
{
x += 3;
}
}
//调用
//委托是指持有一个或多个方法的对象,说白了,其实就是函数指针
//也可以理解为用户自定义的引用类型
//可以把delegate看成是一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型
//调用列表中的方法可以是静态方法也可以是实例方法
//一般先申明,然后创建委托对象。一般我们可以通过+=来组合委托
//MyDel delA = MyIntObj.MyM1;//都是某个方法的名称,也就是其指针了
//MyDel delB = MyIntObj.MyM2;
//MyDel delC = delA + delB;
Test test = new Test();//创建一个测试类实例
PrintFunction pf99;//创建一个空委托
pf99 = test.Print1;//实例化并初始化该委托
//也可以 pf99 = new PrintFunction(test.Print1);//可以省略
pf99 += Test.Print2;//给委托添加3个另外的方法
pf99 += test.Print1;
pf99 += Test.Print2;
if (pf99 != null)
{
pf99();//确认委托有方法,并调用委托(无参方法)
}
else
{
Console.WriteLine("Delegate is empty!");
}
//调用带返回值的委托方法,只需在其他方法中有返回值即可,其执行的是最后一个方法的返回值。
//调用带引用参数的委托 参数值会根据调用列表中的一个或多个方法的返回值而改变。
MyDel mydel = test.ADD2;
mydel += test.ADD3;
int x = 5;
mydel(ref x);
Console.WriteLine("Value: {0}", x);
//匿名方法
//匿名方法是初始化委托是内联声明的方法,即不需要函数了,而是在委托内部自定义函数
//匿名方法的参数列表必须在参数数量,参数类型与位置,修饰符三个方面与委托匹配。
//当然,有时候,我们也可以省略参数列表中的数据声明。params参数必须放在最后。
//delegate void Mydel(int x, params int[] y) ;
//Mydel mydel = delegate(int x, int[] y){ };
// Lambda 表达式
// Mydel mydel = delegate(int x){return x + 1};//匿名方法
// Mydel mydel = (int x) => {return x + 1}; //Lambda 表达式
// Mydel mydel = x => x + 1;
第十四章 事件
发布者与订阅者模式
发布者就是数据的发送端,订阅者是数据的接收端,但是呢,订阅者必须先在发布者这一端注册才行。
需要在事件中使用的代码有5个部分:
对应的代码如下:
//简单点理解:订阅者订阅事件,发布者触发事件,订阅者执行事件处理程序。
利用系统的事件有一个好处不用自己单独在声明委托了,但是不能从发布者传递数据到订阅者去,怎么办?
通过扩展的EventArgs来实现。其实,只需要声明一个派生自EventArgs类即可。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CsharpStart
{
delegate
void Hander();//声明委托
//发布者类
class Incrementer
{
public
event Hander CountedADozen;//创建事件并发布 (事件是特殊的委托)
public
void DoCount()
{
for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
{
if (i % 12 ==0 && CountedADozen != null)
{
CountedADozen();//每增加12,事件触发一次
}
}
}
}
//订阅者类
class Dozens
{
public
int DozensCount { get; private
set; }
public Dozens(Incrementer incrementer)//以发布者类为参数
{
DozensCount = 0;
incrementer.CountedADozen += IncrementerDozensCount;//订阅事件(为事件CountedADozen增加方法)
}
void IncrementerDozensCount()
{
DozensCount++; //声明事件处理程序
}
}
//系统自带的委托类型
public
delegate
void EventHandler(object sender, EventArgs e);
//其中,第一个参数是用来保存触发事件的对象的引用。
//第二个参数用来保存状态信息,指明什么类型适用于该程序。
//用系统自带的委托的话,就不需要自定义委托类型了
//发布者类
class Incrementer1
{
public
event EventHandler CountedADozen1;//创建事件并发布 (事件是特殊的委托)
public
void DoCount()
{
for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
{
if (i % 12 == 0 && CountedADozen1 != null)
{
CountedADozen1(this,null);//每增加12,事件触发一次
//触发事件时使用EventHandler的参数
}
}
}
}
//订阅者类
class Dozens1
{
public
int DozensCount1 { get; private
set; }
public Dozens1(Incrementer1 incrementer1)
{
DozensCount1 = 0;
incrementer1.CountedADozen1 += IncrementerDozensCount1;//订阅事件
}
void IncrementerDozensCount1(object sender,EventArgs e)//事件处理程序的签名(特征)
//必须和系统的委托的签名相匹配
{
DozensCount1++; //声明事件处理程序
}
}
//如何传递数据到事件处理程序中
public
class IncrementerEventArgs : EventArgs
{
public
int IterationCount { get; set; }
}
class Incrementer2
{
public
event EventHandler<IncrementerEventArgs> CountedADozen2;//使用自定义类的泛型委托
public
void DoCount2()
{
IncrementerEventArgs args = new IncrementerEventArgs();//使用自定义的类对象
for (int i = 0; i < 100; ++i)
{
if (i % 12 == 0 && CountedADozen2 != null)
{
args.IterationCount = i;//携带的参数
CountedADozen2(this, args);//可以理解为sendmessage
}
}
}
}
class Dozens2
{
public
int DozensCount2 { get; set; }
public Dozens2(Incrementer2 incrementer)
{
DozensCount2 = 0;
incrementer.CountedADozen2 += IncrementDozensCount;//订阅事件
}
public
void IncrementDozensCount(object sender, IncrementerEventArgs e)//事件处理程序
{
Console.WriteLine("Incremented at iteration : {0} in {1}",e.IterationCount,sender.ToString());
DozensCount2++;
}
}
}
//调用
//1、发布者/订阅者模式,当一个特定的程序事件发生时,程序的其他部分可以得到该事件
//已经发生了的通知,并执行相应的 事件处理程序。调用(invoke)
//5个部分: 1)声明委托。 发布者: 2)创建事件并发布 3)触发事件
// 订阅者: 4)订阅事件 5)事件处理程序
Incrementer incrementer = new Incrementer(); //实例化
Dozens dozensCounter = new Dozens(incrementer);
incrementer.DoCount();//触发事件,调用事件。
Console.WriteLine("Number of dozens = {0}",dozensCounter.DozensCount);
//2、使用系统定义的EventHandler委托
Incrementer1 incrementer1 = new Incrementer1(); //实例化
Dozens1 dozensCounter1 = new Dozens1(incrementer1);
incrementer1.DoCount();//触发事件,调用事件。
Console.WriteLine("Number of dozens1 = {0}", dozensCounter1.DozensCount1);
//3、通过扩展的EventArgs来传递数据,简单的说就是通过派生类来实现
Incrementer2 incrementer2 = new Incrementer2();
Dozens2 dozensCounter2 = new Dozens2(incrementer2);//实例化
incrementer2.DoCount2();//触发事件
//4、我们还可以通过 -= 来移除事件。
//我们在添加事件的时候,不仅仅可以从构造方法中添加(订阅)事件,也可以
//在实例化后,在main函数中订阅事件。
//5、事件访问器 我们可以为事件定义事件访问器 add与remove
什么是委托
委托就是函数的指针。
其和类相似,其实就是用户自定义的引用类型。
委托是包含有序方法列表的对象,这些方法具有相同的签名和返回类型。
MyDel delvar = new MyDel(myInstObj.mym1); < == > MyDel delvar = myInstObj.mym1; //两者之间存成隐式转换。
委托 中还存在给委托赋值,这样会重新指向,组合委托等等。
委托可以添加方法也可以移除方法。 运算符: += -=
调用委托就和调用函数是一样的。
匿名方法:就是没有了 具体的的实例化后的方法名,只有函数体。
注意作用域的范围:
利用正则表达式,可以简化 委托。
代码如下:
delegate
void PrintFunction();//定义一个没有返回值和参数的委托类型
delegate
void MyDel(ref
int x);//引用参数
class Test
{
public
void Print1()
{
Console.WriteLine("Print1 --- instance");
}
public
static
void Print2()
{
Console.WriteLine("Print2 ----- static");
}
public
void ADD2(ref
int x)
{
x += 2;
}
public
void ADD3(ref
int x)
{
x += 3;
}
}
//调用
//委托是指持有一个或多个方法的对象,说白了,其实就是函数指针
//也可以理解为用户自定义的引用类型
//可以把delegate看成是一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型
//调用列表中的方法可以是静态方法也可以是实例方法
//一般先申明,然后创建委托对象。一般我们可以通过+=来组合委托
//MyDel delA = MyIntObj.MyM1;//都是某个方法的名称,也就是其指针了
//MyDel delB = MyIntObj.MyM2;
//MyDel delC = delA + delB;
Test test = new Test();//创建一个测试类实例
PrintFunction pf99;//创建一个空委托
pf99 = test.Print1;//实例化并初始化该委托
//也可以 pf99 = new PrintFunction(test.Print1);//可以省略
pf99 += Test.Print2;//给委托添加3个另外的方法
pf99 += test.Print1;
pf99 += Test.Print2;
if (pf99 != null)
{
pf99();//确认委托有方法,并调用委托(无参方法)
}
else
{
Console.WriteLine("Delegate is empty!");
}
//调用带返回值的委托方法,只需在其他方法中有返回值即可,其执行的是最后一个方法的返回值。
//调用带引用参数的委托 参数值会根据调用列表中的一个或多个方法的返回值而改变。
MyDel mydel = test.ADD2;
mydel += test.ADD3;
int x = 5;
mydel(ref x);
Console.WriteLine("Value: {0}", x);
//匿名方法
//匿名方法是初始化委托是内联声明的方法,即不需要函数了,而是在委托内部自定义函数
//匿名方法的参数列表必须在参数数量,参数类型与位置,修饰符三个方面与委托匹配。
//当然,有时候,我们也可以省略参数列表中的数据声明。params参数必须放在最后。
//delegate void Mydel(int x, params int[] y) ;
//Mydel mydel = delegate(int x, int[] y){ };
// Lambda 表达式
// Mydel mydel = delegate(int x){return x + 1};//匿名方法
// Mydel mydel = (int x) => {return x + 1}; //Lambda 表达式
// Mydel mydel = x => x + 1;
第十四章 事件
发布者与订阅者模式
发布者就是数据的发送端,订阅者是数据的接收端,但是呢,订阅者必须先在发布者这一端注册才行。
需要在事件中使用的代码有5个部分:
对应的代码如下:
//简单点理解:订阅者订阅事件,发布者触发事件,订阅者执行事件处理程序。
利用系统的事件有一个好处不用自己单独在声明委托了,但是不能从发布者传递数据到订阅者去,怎么办?
通过扩展的EventArgs来实现。其实,只需要声明一个派生自EventArgs类即可。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CsharpStart
{
delegate
void Hander();//声明委托
//发布者类
class Incrementer
{
public
event Hander CountedADozen;//创建事件并发布 (事件是特殊的委托)
public
void DoCount()
{
for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
{
if (i % 12 ==0 && CountedADozen != null)
{
CountedADozen();//每增加12,事件触发一次
}
}
}
}
//订阅者类
class Dozens
{
public
int DozensCount { get; private
set; }
public Dozens(Incrementer incrementer)//以发布者类为参数
{
DozensCount = 0;
incrementer.CountedADozen += IncrementerDozensCount;//订阅事件(为事件CountedADozen增加方法)
}
void IncrementerDozensCount()
{
DozensCount++; //声明事件处理程序
}
}
//系统自带的委托类型
public
delegate
void EventHandler(object sender, EventArgs e);
//其中,第一个参数是用来保存触发事件的对象的引用。
//第二个参数用来保存状态信息,指明什么类型适用于该程序。
//用系统自带的委托的话,就不需要自定义委托类型了
//发布者类
class Incrementer1
{
public
event EventHandler CountedADozen1;//创建事件并发布 (事件是特殊的委托)
public
void DoCount()
{
for (int i = 0; i < 100; i++) //事件调用函数,或者称为触发事件函数
{
if (i % 12 == 0 && CountedADozen1 != null)
{
CountedADozen1(this,null);//每增加12,事件触发一次
//触发事件时使用EventHandler的参数
}
}
}
}
//订阅者类
class Dozens1
{
public
int DozensCount1 { get; private
set; }
public Dozens1(Incrementer1 incrementer1)
{
DozensCount1 = 0;
incrementer1.CountedADozen1 += IncrementerDozensCount1;//订阅事件
}
void IncrementerDozensCount1(object sender,EventArgs e)//事件处理程序的签名(特征)
//必须和系统的委托的签名相匹配
{
DozensCount1++; //声明事件处理程序
}
}
//如何传递数据到事件处理程序中
public
class IncrementerEventArgs : EventArgs
{
public
int IterationCount { get; set; }
}
class Incrementer2
{
public
event EventHandler<IncrementerEventArgs> CountedADozen2;//使用自定义类的泛型委托
public
void DoCount2()
{
IncrementerEventArgs args = new IncrementerEventArgs();//使用自定义的类对象
for (int i = 0; i < 100; ++i)
{
if (i % 12 == 0 && CountedADozen2 != null)
{
args.IterationCount = i;//携带的参数
CountedADozen2(this, args);//可以理解为sendmessage
}
}
}
}
class Dozens2
{
public
int DozensCount2 { get; set; }
public Dozens2(Incrementer2 incrementer)
{
DozensCount2 = 0;
incrementer.CountedADozen2 += IncrementDozensCount;//订阅事件
}
public
void IncrementDozensCount(object sender, IncrementerEventArgs e)//事件处理程序
{
Console.WriteLine("Incremented at iteration : {0} in {1}",e.IterationCount,sender.ToString());
DozensCount2++;
}
}
}
//调用
//1、发布者/订阅者模式,当一个特定的程序事件发生时,程序的其他部分可以得到该事件
//已经发生了的通知,并执行相应的 事件处理程序。调用(invoke)
//5个部分: 1)声明委托。 发布者: 2)创建事件并发布 3)触发事件
// 订阅者: 4)订阅事件 5)事件处理程序
Incrementer incrementer = new Incrementer(); //实例化
Dozens dozensCounter = new Dozens(incrementer);
incrementer.DoCount();//触发事件,调用事件。
Console.WriteLine("Number of dozens = {0}",dozensCounter.DozensCount);
//2、使用系统定义的EventHandler委托
Incrementer1 incrementer1 = new Incrementer1(); //实例化
Dozens1 dozensCounter1 = new Dozens1(incrementer1);
incrementer1.DoCount();//触发事件,调用事件。
Console.WriteLine("Number of dozens1 = {0}", dozensCounter1.DozensCount1);
//3、通过扩展的EventArgs来传递数据,简单的说就是通过派生类来实现
Incrementer2 incrementer2 = new Incrementer2();
Dozens2 dozensCounter2 = new Dozens2(incrementer2);//实例化
incrementer2.DoCount2();//触发事件
//4、我们还可以通过 -= 来移除事件。
//我们在添加事件的时候,不仅仅可以从构造方法中添加(订阅)事件,也可以
//在实例化后,在main函数中订阅事件。
//5、事件访问器 我们可以为事件定义事件访问器 add与remove
相关文章推荐
- c#复习总结
- 【C#基础】【ADO.NET】复习、总结
- 【C#复习总结】垃圾回收机制(GC)2
- c#复习总结
- 【C#复习总结】细说表达式树
- 【C#复习总结】细说泛型委托
- C#总结复习5(需要进一步复习)
- 【C#复习总结】dynamic
- 图解C# Console 输出和Console相关编程复习总结
- 【C#复习总结】垃圾回收机制(GC)1
- 【C#复习总结】细说委托
- 复习总结C#中的string的常用容易混乱的方法
- 期末考试复习c#时总结的抽象类与接口的一些区别
- 【C#复习总结】 Async 和 Await 的异步编程
- 【C# 复习总结】类、继承和接口
- 【C#复习总结】细说 Lambda表达式
- 【C#复习总结】析构函数
- C#5 复习总结循环 迭代和穷举
- 【C#复习总结】多线程编程
- c#基础--方法(复习总结)