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();

posted @ 2010-12-12 22:05  规定  阅读(295)  评论(0编辑  收藏  举报