C#委托(Delegate)事件(Event)应用详解 (原)
C#委托(Delegate)事件(Event)应用详解 (原)
如果委托是有返回值的函数,则只能调用最后一个委托函数:
//测试有返回值的多播。
public void TestReturnValueEvent()
{
A a = new A();
B b = new B();
//产生有返回值的多播事件
b.ReturnValueEvent += new GetValueInvoke(a.GetValueA); //注:GetValueA()函数返回int 100
b.ReturnValueEvent += new GetValueInvoke(a.GetValueB); //注:GetValueB()函数返回int 200
b.TestEvent1(); //显示结果200; =a.GetValueB();
A a1 = new A();
B b1 = new B();
//产生有返回值的多播事件- 顺序相反
b1.ReturnValueEvent += new GetValueInvoke(a1.GetValueB); //注:GetValueB()函数返回int 200
b1.ReturnValueEvent += new GetValueInvoke(a1.GetValueA); //注:GetValueA()函数返回int 100
b1.TestEvent1(); //显示结果100; =a1.GetValueA();
}
证明:有返回值的函数用于多播是失败的!
结合测试用例思考:
为什么b.SetDelegateMethod()与b.MyEven += new MethodInvoke(a.A_Method)显示结果一致,但有什么区别呢?
解释:b.SetDelegateMethod()是调用SetDelegateMethod方法给b对象内的_delegateMethod变量赋值。
而b.MyEven += new MethodInvoke(a.A_Method)是给b.MyEven事件绑定一个MethodInvoke类型方法。使用"+="操作符表示给b.MyEven事件同时绑定多个方法,这就是C#内的多播应用。
因此b.SetDelegateMethod()是调用方法而b.MyEven += new MethodInvoke(a.A_Method)是给事件绑定方法。
如转载请注明出处:www.csframework.com C/S框架网
扫一扫加作者微信
演示程序下载
委托 (Delegate)
多播委托(Multi-Broadcast Delegate)
源代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace CSFramework.Tech.Delegate
{
//测试用例
public class TestClasses
{
//测试委托
public void TestDelegate()
{
A a = new A();
B b = new B();
b.SetDelegateMethod(a.A_Method); //给A对象设置一个委托,该委托是委托A对象内的A_Method方法
b.TestDelegate(); //测试这个委托。注意提示信息
}
//测试事件
public void TestEvent()
{
A a = new A();
B b = new B();
//给b对象的MyEven事件绑定一个委托方法,该委托是委托A对象内的A_Method方法
b.MyEven += new MethodInvoke(a.A_Method);
b.TestEvent(); //测试这个事件。注意提示信息
}
//测试多播
public void TestMultiBroadcast()
{
A a = new A();
B b = new B();
b.MyEven += new MethodInvoke(a.A_Method); //给b对象的MyEven事件绑定一个委托方法A_Method
b.MyEven += new MethodInvoke(a.AA_Method); //给b对象的MyEven事件绑定一个委托方法AA_Method
b.TestEvent(); //测试这个事件。注意提示信息
}
private WriteLogMethod _logMethod = null;
private Form _owner = null;
//测试线程内调用委托
public void TestDelegateInThread(Form owner,WriteLogMethod method)
{
_logMethod = method;
_owner = owner;
Thread t = new Thread(new ThreadStart(Run));
t.Start();//开始运行线程
}
//多线程内的方法
private void Run()
{
//
//直接调用_logMethod()试试? 会抛出异常:
//Cross-thread operation not valid: Control ''''listBox1'''' accessed from a thread other than the thread it was created on.
//
/*
_logMethod("多线程内的输出数据1");
_logMethod("多线程内的输出数据2");
_logMethod("多线程内的输出数据3");
*/
// Control.Invoke()方法说明:
// Executes the specified delegate, on the thread that owns the control''''s underlying
// window handle, with the specified list of arguments.
//
_owner.Invoke(_logMethod, "多线程内的输出数据1");
_owner.Invoke(_logMethod, "多线程内的输出数据2");
_owner.Invoke(_logMethod, "多线程内的输出数据3");
}
}
/// <summary>
/// 定义一个由多线程调用的委托类型.用于显示多线程内输出的数据.
/// </summary>
public delegate void WriteLogMethod(string log);
/// <summary>
/// 定义一个自定义委托类型
/// </summary>
public delegate void MethodInvoke();
//测试类A
public class A
{
public void A_Method()
{
MessageBox.Show("A对象内的A_Method方法!");
}
public void AA_Method()
{
MessageBox.Show("A对象内的AA_Method方法!");
}
}
//测试类B
public class B
{
public void B_Method()
{
MessageBox.Show("B对象内的方法!");
}
//委托方法变量
private MethodInvoke _delegateMethod;
public void SetDelegateMethod(MethodInvoke method)
{
_delegateMethod = method;
}
//测试由外部传进来的委托事件.
public void TestDelegate()
{
if (_delegateMethod != null) _delegateMethod();
}
//事件变量
private event MethodInvoke _MyEvent = null;
/// <summary>
/// 给对象定义一个事件。
/// 注意事件定义的标准语法,add,remove
/// </summary>
public event MethodInvoke MyEven
{
add { _MyEvent += new MethodInvoke(value); }
remove { _MyEvent -= new MethodInvoke(value); }
}
//测试对象的事件。
public void TestEvent()
{
if (_MyEvent != null) _MyEvent();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace CSFramework.Tech.Delegate
{
//测试用例
public class TestClasses
{
//测试委托
public void TestDelegate()
{
A a = new A();
B b = new B();
b.SetDelegateMethod(a.A_Method); //给A对象设置一个委托,该委托是委托A对象内的A_Method方法
b.TestDelegate(); //测试这个委托。注意提示信息
}
//测试事件
public void TestEvent()
{
A a = new A();
B b = new B();
//给b对象的MyEven事件绑定一个委托方法,该委托是委托A对象内的A_Method方法
b.MyEven += new MethodInvoke(a.A_Method);
b.TestEvent(); //测试这个事件。注意提示信息
}
//测试多播
public void TestMultiBroadcast()
{
A a = new A();
B b = new B();
b.MyEven += new MethodInvoke(a.A_Method); //给b对象的MyEven事件绑定一个委托方法A_Method
b.MyEven += new MethodInvoke(a.AA_Method); //给b对象的MyEven事件绑定一个委托方法AA_Method
b.TestEvent(); //测试这个事件。注意提示信息
}
private WriteLogMethod _logMethod = null;
private Form _owner = null;
//测试线程内调用委托
public void TestDelegateInThread(Form owner,WriteLogMethod method)
{
_logMethod = method;
_owner = owner;
Thread t = new Thread(new ThreadStart(Run));
t.Start();//开始运行线程
}
//多线程内的方法
private void Run()
{
//
//直接调用_logMethod()试试? 会抛出异常:
//Cross-thread operation not valid: Control ''''listBox1'''' accessed from a thread other than the thread it was created on.
//
/*
_logMethod("多线程内的输出数据1");
_logMethod("多线程内的输出数据2");
_logMethod("多线程内的输出数据3");
*/
// Control.Invoke()方法说明:
// Executes the specified delegate, on the thread that owns the control''''s underlying
// window handle, with the specified list of arguments.
//
_owner.Invoke(_logMethod, "多线程内的输出数据1");
_owner.Invoke(_logMethod, "多线程内的输出数据2");
_owner.Invoke(_logMethod, "多线程内的输出数据3");
}
}
/// <summary>
/// 定义一个由多线程调用的委托类型.用于显示多线程内输出的数据.
/// </summary>
public delegate void WriteLogMethod(string log);
/// <summary>
/// 定义一个自定义委托类型
/// </summary>
public delegate void MethodInvoke();
//测试类A
public class A
{
public void A_Method()
{
MessageBox.Show("A对象内的A_Method方法!");
}
public void AA_Method()
{
MessageBox.Show("A对象内的AA_Method方法!");
}
}
//测试类B
public class B
{
public void B_Method()
{
MessageBox.Show("B对象内的方法!");
}
//委托方法变量
private MethodInvoke _delegateMethod;
public void SetDelegateMethod(MethodInvoke method)
{
_delegateMethod = method;
}
//测试由外部传进来的委托事件.
public void TestDelegate()
{
if (_delegateMethod != null) _delegateMethod();
}
//事件变量
private event MethodInvoke _MyEvent = null;
/// <summary>
/// 给对象定义一个事件。
/// 注意事件定义的标准语法,add,remove
/// </summary>
public event MethodInvoke MyEven
{
add { _MyEvent += new MethodInvoke(value); }
remove { _MyEvent -= new MethodInvoke(value); }
}
//测试对象的事件。
public void TestEvent()
{
if (_MyEvent != null) _MyEvent();
}
}
}
如果委托是有返回值的函数,则只能调用最后一个委托函数:
//测试有返回值的多播。
public void TestReturnValueEvent()
{
A a = new A();
B b = new B();
//产生有返回值的多播事件
b.ReturnValueEvent += new GetValueInvoke(a.GetValueA); //注:GetValueA()函数返回int 100
b.ReturnValueEvent += new GetValueInvoke(a.GetValueB); //注:GetValueB()函数返回int 200
b.TestEvent1(); //显示结果200; =a.GetValueB();
A a1 = new A();
B b1 = new B();
//产生有返回值的多播事件- 顺序相反
b1.ReturnValueEvent += new GetValueInvoke(a1.GetValueB); //注:GetValueB()函数返回int 200
b1.ReturnValueEvent += new GetValueInvoke(a1.GetValueA); //注:GetValueA()函数返回int 100
b1.TestEvent1(); //显示结果100; =a1.GetValueA();
}
证明:有返回值的函数用于多播是失败的!
结合测试用例思考:
为什么b.SetDelegateMethod()与b.MyEven += new MethodInvoke(a.A_Method)显示结果一致,但有什么区别呢?
解释:b.SetDelegateMethod()是调用SetDelegateMethod方法给b对象内的_delegateMethod变量赋值。
而b.MyEven += new MethodInvoke(a.A_Method)是给b.MyEven事件绑定一个MethodInvoke类型方法。使用"+="操作符表示给b.MyEven事件同时绑定多个方法,这就是C#内的多播应用。
因此b.SetDelegateMethod()是调用方法而b.MyEven += new MethodInvoke(a.A_Method)是给事件绑定方法。
如转载请注明出处:www.csframework.com C/S框架网
扫一扫加作者微信
演示程序下载
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
NewDoc C/S框架网