C#委托本质探索 四、方法变量内、外混合调用
// delegate定义的仅仅是规则,完全没有实体,应该把它定义的东西称做--方法接口
// 测试3.方法变量 增加内部调用
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1.FourthTest
{
delegate void 方法接口(string 参数);
class FourthTest
{
public void DoTest1()
{
基础对象 对象实例 = new 基础对象();
Console.WriteLine("测试1:");
//测试方法变量调用
Console.WriteLine();
Console.Write("方法变量调用:");
对象实例.事务处理("最初事务");
//追加方法变量值
Console.WriteLine();
Console.Write("追加方法变量值:");
对象实例.方法变量 += new 方法接口(this.新的方法实体);
对象实例.方法变量("追加事务");
对象实例.查看原实体情况();
//去除方法变量值
Console.WriteLine();
Console.Write("去除方法变量值:");
对象实例.方法变量 -= new 方法接口(this.新的方法实体);
对象实例.方法变量("去除追加事务后执行一个事务");
//改变方法变量
Console.WriteLine();
Console.Write("改变方法变量:");
对象实例.方法变量 = new 方法接口(this.新的方法实体);
对象实例.方法变量("重定向处理事务");
对象实例.查看原实体情况();
}
public void DoTest2()
{
基础对象 对象实例 = new 基础对象();
Console.WriteLine("测试2:");
//测试方法变量调用
Console.WriteLine();
Console.Write("方法变量调用:");
对象实例.事务处理("最初事务");
//追加方法变量值
Console.WriteLine();
Console.Write("追加方法变量值:");
对象实例.方法变量 += this.新的方法实体;
对象实例.方法变量("追加事务");
对象实例.查看原实体情况();
//去除方法变量值
Console.WriteLine();
Console.Write("去除方法变量值:");
对象实例.方法变量 -= this.新的方法实体;
对象实例.方法变量("去除追加事务后执行一个事务");
//改变方法变量
Console.WriteLine();
Console.Write("改变方法变量:");
对象实例.方法变量 -= this.新的方法实体;
对象实例.方法变量("重定向处理事务");
对象实例.查看原实体情况();
}
private void 新的方法实体(string 方法参数)
{
Console.WriteLine(方法参数.ToString());
}
}
class 基础对象
{
public 方法接口 方法变量;
public 基础对象()
{
//为方法变量实例化
方法变量 = new 方法接口(this.原方法实体);
//方法变量 = this.原方法实体;
}
//定义原方法实体
private void 原方法实体(string 方法参数)
{
Console.WriteLine("原方法实体:" + 方法参数.ToString());
}
public void 事务处理(string 事务)
{
方法变量(事务);
}
public void 查看原实体情况()
{
this.原方法实体("查看原实体情况");
MySize a = new MySize(5, 5);
MySize b = a;
}
}
class MySize
{
int _width;
int _height;
public MySize(int width, int height)
{
_width = width;
_height = height;
}
}
// 在这个测试运行过程中,基础对象的"事务处理"中调用"方法变量"的执行情况受到影响.
// 使用 += 保留"事务处理"中对"方法变量"调用的原始方法.
// 使用 = 清除"方法变量"原有值,重定向到新的方法上.
// 我们实现了从外部改变"基础对象"的事务处理过程.
// 注释"基础对象"的构造方法中 方法变量 = new 方法接口(this.原方法实体);
// 换为 方法变量 = this.原方法实体;
// 观察"查看原实体情况"的执行结果,发现没有变化,说明改变方法变量值时不会改变原方法实体指针.
// int a = 5;
// int b = a;
// b = 3; 这时a还是5.
// 这样写Int b = new Int(a);挺花哨,目前看完全没有用.
// 上面这个例子就是事件的原理.以按钮的点击事件为例:
// 定义一个全局的方法接口 MouseEventHandler.
// Button类内部定义一个公开的方法变量 Click, 类型为 MouseEventHandler.
// Button类内部WndProc里消息循环捕捉到WM_LBUTTONUP时调用Click.
// Button类内部定义一个 OnClick方法实体,方便Click,并且实现画界面功能.
// 我们在外部写遵循MouseEventHandler方法接口的方法 MyButton_Click(...)
// 把我们自己的方法实体挂接到MyButton.Click方法变量上
// 这样,MyButton实例的WndProc消息处理过程执行到方法变量Click时,
// 先执行了内部的OnClick功能,然后执行了我们的MyButton_Click()方法.
// 在事件定义时,C#又增加了一个event修饰,这样我就不能在外部用=操作给Click直接赋值,只能+=方式操作.
// 事实上真正的Button.Click实现比上面说的要复杂,可以说delegate仅是完成了事件的部分核心,
// 但是我们自己要实现一个自定义事件这样做应该可以了.
// 第五个例子研究按钮点击真正的内部实现,这个有点跑题.不仅仅是delegate的用法了.
}
// 测试代码
FourthTest.FourthTest test4 = new FourthTest.FourthTest();
test4.DoTest1();
Console.ReadLine();
test4.DoTest2();