简单的说,Delegate就是C语言中的指向函数的指针,不同之处就是Delegate要比C的指向函数的指针功能更丰富,Delegate可以引用Instance Method(实例方法)并且可以同时引用多个函数。
Delegate的声明
delegate 返回值类型 Delegate类型名(参数序列);
注意,这里定义的【Delegate类型名】和普通定义的用户类具有相同的性质,并且缺省是继承自System.Delegate。所有和返回值类型相同的函数都可以作为参数带入到这个类中,下面看一个具体的例子:
例1
using System;
// MyDelegate
delegate void MyDelegate(int a);
class DelegateTest
{
static void Main()
{
// MyDelegate 这个类中把函数名作为参数带入
MyDelegate a = new MyDelegate(A); //在C#2.0中可以直接写成 MyDelegate a = A;
a(123); // 通过代理调用函数,在这里就是调用A(123)
}
static void A(int n)
{
Console.Write("A({0})调用成功。\n", n);
}
}
执行结果:A 123 调用成功。
下面看一个Instance Mothod调用的例子
例2
using System;
///
/// 消息显示代理
///
delegate void ShowMessage();
class Person
{
string name;
public Person(string name){this.name = name;}
public void ShowName(){Console.Write("姓名: {0}\n", this.name);}
};
class DelegateTest
{
static void Main()
{
Person p = new Person("小王");
//Instance Method 代入
ShowMessage show = new ShowMessage(p.ShowName);
show();
}
}
执行结果:
姓名 小王
多个方法同时调用的例子
例3
using System;
///
/// 消息显示代理
///
delegate void ShowMessage();
class DelegateTest
{
static void Main()
{
ShowMessage a = new ShowMessage(A);
a += new ShowMessage(B);
a += new ShowMessage(C);
a();
}
static void A(){Console.Write("A 被调用。\n");}
static void B(){Console.Write("B被调用。\n");}
static void C(){Console.Write("C 被调用。\n");}
}
执行结果:
A 被调用。
B 被调用。
C 被调用。
注: +=加入的方法被顺序调用。
Delegate还有一个很大的特点是实现非同期掉调用。
同期调用(Synchronous Call)是指函数调用后不能马上返回,只有函数执行完毕才能返回的调用。相反,非同期调用(Asynchronous Call)则在函数调用的瞬间就返回。所以,非同期调用可以用来实现多线程。
一旦定义了Delegate类型,C#的编译器就会自动生成BeginInvoke和EndInvoke这两个函数,用BeginInvoke开启非同期的调用,用EndInvoke来等待非同期调用的返回。
例如定义了一个 delegate int ShowMessage(int n, ref int p, out int q); 这样的Delegate ,编译器会自动生成下面的2个函数
IAsyncResult BeginInvoke(int n, ref int p, out int q, AsyncCallback callback, object state);
int EndInvoke(ref int p, out int q, IAsyncResult ar);
下面是给一个Delegate实现的非同期调用的例子
例4
using System;
using System.Threading;
namespace A
{
///
/// 消息显示代理
///
public delegate void ShowMessage(int n);
public class DelegateTest
{
static void Main()
{
const int N = 6;
ShowMessage asyncCall = new ShowMessage(AsynchronousMethod);
// asyncCall 非同期调用开启
IAsyncResult ar = asyncCall.BeginInvoke(N, null, null);
//这个循环部分会与asyncCall代理调用的函数同时执行。
for(int i=0; i{
Thread.Sleep(600);
Console.Write("Main ({0})\n", i);
}
// 等待 asyncCall 处理的结束
asyncCall.EndInvoke(ar);
Console.Write(" 处理结束 \n");
}
static void AsynchronousMethod(int n)
{
for(int i=0; i{
Thread.Sleep(1000);
Console.Write("AsynchronousMethod ({0})\n", i);
}
}
static void B(IAsyncResult ar){}
}
}
执行结果:
Main (0)
AsynchronousMethod (0)
Main (1)
Main (2)
AsynchronousMethod (1)
Main (3)
Main (4)
AsynchronousMethod (2)
Main (5)
AsynchronousMethod (3)
AsynchronousMethod (4)
AsynchronousMethod (5)
处理结束
没有评论:
发表评论