c# 委托与事件理解

538 阅读1分钟

委托

委托三要素

1. 声明一个委托

public delegate void Call(string str);

委托就相当于函数指针,这样理解起来就简单了。

2. 创建委托实例

Call c = new Call(callback);

3. 调用委托方法

c.Invoke(str);
或者
c(str)

匿名委托函数

Call ccc = delegate (string str)
{
    Console.WriteLine(str + "----匿名");
};
ccc(data);

引申为 lambda

Call cccc = (str) =>
{
    Console.WriteLine(str + "----lambda");
};
cccc(data);

多播

c += callback2;
c -= callback2;

实例1

class B
{
    public static void Callback(string str) {
        Console.WriteLine(str + "Callback");
    }

    public static void Callback1(string str)
    {
        Console.WriteLine(str + "Callback1");
    }
}
class A
    {
        public delegate void Call(string str);

        public Call cc;
        public void getStringData(string data) {
            cc = B.Callback;
            cc.Invoke(data + "====");
            Call c = new Call(B.Callback);
            c += B.Callback1; // 多播
            c(data + "-----");

            Call ccc = delegate (string str)
            {
                Console.WriteLine(str + "----匿名");
            };
            ccc(data);
            
            Call cccc = (str) =>
            {
                Console.WriteLine(str + "----lambda");
            };
            cccc(data);
        }
    }

测试

new A().getStringData("data");

结果

data====Callback
data-----Callback
data-----Callback1
data----匿名
data----lambda

事件

事件三部曲

1. 声明事件(包含声明事件的委托类型)

public delegate void Call(string str); 
public event Call ce;

2. 注册(或者说是订阅)


    // 注册回调,可多播,同时注册多个
    ce += B.Callback_event;
    ce += new B().InstaceCallback;
    ce += (str) =>
    {
        Console.WriteLine(str + "----lambda event ");
    };

3.调用

ce(data);

实例2(base on 实例1)

class A
    {
        public event Call ce;
        public delegate void Call(string str);

        public Call cc;
        public void getStringData(string data) {
            cc = B.Callback;
            cc.Invoke(data + "====");
            Call c = new Call(B.Callback);
            c += B.Callback1; // 多播
            c(data + "-----");

            Call ccc = delegate (string str)
            {
                Console.WriteLine(str + "----匿名");
            };
            ccc(data);

            Call cccc = (str) =>
            {
                Console.WriteLine(str + "----lambda");
            };
            cccc(data);

            // 注册回调,可多播,同时注册多个
            ce += B.Callback_event;
            ce += new B().InstaceCallback;
            ce += (str) =>
            {
                Console.WriteLine(str + "----lambda event ");
            };
            // 调用
            ce(data);
        }
    }
class B
    {
        public static void Callback(string str) {
            Console.WriteLine(str + "Callback");
        }

        public static void Callback1(string str)
        {
            Console.WriteLine(str + "Callback1");
        }

        public static void Callback_event(string str) {
            Console.WriteLine(str + "----callback_event");
        }

        public void InstaceCallback(string str) {
            Console.WriteLine(str + "----InstaceCallback");
        }
    }
如果用发布订阅模式来理解的话,类A相当于发布器类,类B相当于订阅器类。

测试

new A().getStringData("data");

结果

data====Callback
data-----Callback
data-----Callback1
data----匿名
data----lambda
data----callback_event
data----InstaceCallback
data----lambda event