C#之入门总结_委托_16

来源:互联网 发布:python random.sample 编辑:程序博客网 时间:2024/05/18 13:06
# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。


委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同标签的方法。

委托的声明和方法的声明时一样,只不过多了一个delegate修饰符

委托不是方法,而是一种类型
委托是引用类型

如下两种委托限定了回调方法的类型
public delegate int YyDelegate();

public delegate int MyDelegate (string s);

声明委托后,我们可以通过new关键字来创建委托。委托的构造方法中需要填入的是方法的名 ,注意不带有参数:
例如:
delegate void MyDelegate();
MyDelegate mydel = new MyDelegate(Test);

需要回调的方法:
void Test()
{
    Console.WriteLine("YY真帅");
}


我们还可以直接赋值:
MyDelegate del = Test;


  public delegate void MyDelegate();
    public delegate int BuyWoodDelegate(int num1,int num2);
    class Program
    {
        static void Main(string[] args)
        {
            //MyDelegate dele = new MyDelegate(Test);
            //dele();

            //MyDelegate del = Test;
            //del();

            Woker woker = new Woker();
            //MyDelegate buyWood = woker.BuyWood;
            ////让方法执行
            //buyWood();
            ////
            //buyWood.Invoke();


            BuyWoodDelegate buy = woker.BuyWood;
            int count = buy.Invoke(2000, 199);
            Console.WriteLine("买了"+count+"根木头");



            //Test();

                 

        }
        //方法的签名: 返回值类型相同  参数列表相同  
        static void Test()
        {
            Console.WriteLine("*********************");
        }

    }

class Woker
    {

        public void BuyWood()
        {
            Console.WriteLine("老板,我已经买好木头了");
        }
        public int BuyWood(int money,int price)
        {

            return money / price;
        }
    }

多播委托

委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。

使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播

在生活办公中使用的打印机就是一个多播的一个实例:
例如张三需要打印一个文件,打印耗时5分钟,李四也需要打印一个文件,那么李四只需要向打印机发出打印文件的命令即可,在打印张三的文件结束后,再打印李四的文件。如果李四反悔了,就可以撤销刚才的操作。

  delegate void PrintDelegate(string str);
    class Program
    {
        static void Main(string[] args)
        {
            //第一次不适用+=操作
            PrintDelegate print = Task01;
            print("C#编程之道");
            //print = Task02;
            print = Task03;
            print("三生三世");
        }
        static void Task01(string str)
        {
            Thread.Sleep(3000);
            Console.WriteLine("我帮你打印好了"+str);               
        }
        static void Task02(string str)
        {
            Thread.Sleep(5000);
            Console.WriteLine("我帮你打印好了" + str);
            
            Console.WriteLine(5);
        }
        static void Task03(string str)
        {
            Thread.Sleep(7000);
            Console.WriteLine("我帮你打印好了" + str);
            
            Console.WriteLine(7);
        }
    }

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。

事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。

发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。

订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

namespace 事件案例1
{
    class Program
    {
        static void Main(string[] args)
        {
            Promulgator p = new Promulgator();
            Subscriber xiaoming = new Subscriber("aa");
            p.AddEvent(xiaoming.Notice);
            Subscriber wangyao = new Subscriber("bb");
            p.AddEvent(wangyao.Notice);
            Subscriber yadong = new Subscriber("cc");
            p.AddEvent(yadong.Notice);
            p.ExeEvent("老板来了,各就各位");
        }
    }
}
namespace 事件案例1
{

    delegate void MyDelegate(string str);
    class Promulgator
    {
        public event MyDelegate handler;
        public void AddEvent(MyDelegate func)
        {
            handler += func;
        }
        public void SubEvent(MyDelegate func)
        {
            handler -= func;
        }
        public void ExeEvent(string str)
        {
            if (handler!=null)
            {
                handler.Invoke(str);
            }
        }
    }
}

namespace 事件案例1
{
    class Subscriber
    {
        private string name;
        public Subscriber(string name)
        {
            this.Name = name;
        }
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
        public void Notice(string str)
        {
            Console.WriteLine("{0},{1}",Name,str);
        }

    }
}

原创粉丝点击