目前我所理解我委托和事件就是可以把方法当成参数一样使用,能确定类型但不知道具体的方法时用委托。委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来使用,使程序具有更好的可拓展性。事件封装了委托类型的变量,使得在类的内部它总是Private的。在类的外部,注册“+=”和注销“-=”。类似于声明一个封装的委托类型的变量而已。委托和事件也是Observer设计模式的经典呈现。代码实现:
/***
* 学习使用委托和事件
* 假设是一个游戏,主角捡到到100宝石,通知分数加一,通知UI显示游戏胜利
***/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 委托实例
{
public class StudyDelegate
{
private int gemNum; //变量表示宝石数量
public delegate void Gem(int param); //声明一个委托(宝石)
public event Gem GemEvent; //声明一个事件
/// <summary>
/// 收集宝石的方法
/// </summary>
public void CollectGem()
{
for(int i = 0; i <= 100; i++)
{
gemNum = i;
if (gemNum > 95)
{
if (GemEvent != null)
{
GemEvent(gemNum);
}
}
}
}
}
public class Score
{
public void AddScore(int param)
{
Console.WriteLine("已经收集了{0}个宝石", param);
Console.ReadLine();
}
}
public class UI
{
public void UIShow(int param)
{
Console.WriteLine("收集了{0}个宝石,游戏快要胜利了", param);
Console.ReadLine();
}
}
class Program
{
static void Main(string[] args)
{
StudyDelegate study = new StudyDelegate();
Score score = new 委托实例.Score();
UI ui = new 委托实例.UI();
study.GemEvent += score.AddScore; //注册分数委托事件
study.GemEvent += ui.UIShow; //注册ui显示委托事件
study.CollectGem(); //收集宝石,会自动调用注册过对象的方法
}
}
}
输出结果:
Action 委托 :
Action委托是官方内置的可以指向一个没有参数和返回值的方法;例如:
Action a=printString;
public static void printString()
{
console.writeLine("hello world");
}
a();
Action委托也可以带参数,要加入泛型格式,例如:
Action<int,int>a=Add;
public static void Add(int num1,int num2)
{
console.writeline(num1+num2);
}
a(2,3);
输出结果为5.
Func委托 :
可以而且必须有一个返回值 也是用泛型格式。
多播委托:
前面使用的委托都只包含一个方法的调用,但是委托也可以包含多个方法,这种委托叫做多播委托。使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。
Actionaction1 = Test1;
action2+=Test2;
action2-=Test1;
多播委托包含一个逐个调用的委托集合,如果通过委托调用的其中一个方法抛出异常,整个迭代就会停止。
Action a1 = Method1;
a1+=Method2;
Delegate[]delegates=a1.GetInvocationList();
foreach(delegate d in delegates){
//d();
d.DynamicInvoke(null);
}
遍历多播委托中所有的委托,然后单独调用