C#语法手册

委托与事件


委托与事件的基本语法以及 Action 和 Func 泛型委托的使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSGDemoCSG013
{

    //https://docs.microsoft.com/zh-cn/dotnet/csharp/delegate-class
    //https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/event

    //#csg013-01
    //声明一个委托
    //委托的基类均为类 System.MulticastDelegate,
    //这是一个特殊的类型,编译器和其他工具可以从该类派生,但是你不能继承它。delegate类也是如此。
    //简单的说delegate代表一个特定签名的“方法”,它是一个代表特定签名方法的类,你可以使用相同签名的方法或lambada表达式来实例它。
    public delegate void ASimpleDelegate(string value);

    class DelegateSample
    {
        //#csg013-02
        //使用上面定义的委托类型声明一个委托字段
        public ASimpleDelegate simpleDelegate;

        DelegateSample()
        {
            //#csg013-03
            //使用相同签名的方法实例化委托
            this.simpleDelegate = new ASimpleDelegate(ASimpleMethod);
        }

        public void CallDelegate()
        {
            //#csg013-04
            //直接调用委托
            this.simpleDelegate("value for delegate");
        }

        public void ASimpleMethod(string value)
        {
            Console.WriteLine(value);
        }


        public void AnonymousFunctions()
        {
            //#csg013-05
            //使用匿名方法实例化委托
            //C#2.0 开始,你可以使用匿名方法来实例化委托
            ASimpleDelegate testDelB = delegate (string s) { Console.WriteLine(s); };

            //#csg013-06
            //C#3.0 开始,你可以使用lambda来实例化委托
            ASimpleDelegate testDelC = (x) => { Console.WriteLine(x); };

        }



        public void ActionFunctionLambada()
        {
            //#csg013-10
            //lambada与Action及Func
            //目前我们最常用的委托类型是 Action 和 Func, Action代表了没有返回值的方法, Func代表了有返回值的方法。
            //之前我们使用委托时候需要先定义一个委托类型,有了 lambada 和 Action与Func类型之后我们就可以非常方便的使用委托了。

            //#csg013-07
            //使用lambada创建一个Action委托
            Action<string> action_1 = (s) => { Console.WriteLine(s); };

            //#csg013-08
            //使用lambada创建一个Func委托
            Func<int, string> func_1 = (i) => { return $"input value is {i.ToString()}"; };

            //#csg013-09
            //在以Action或Function为参数的方法中直接输入lambada
            FunctionWithDelegateParams(s => { Console.WriteLine(s); });

        }

        //#csg013-09
        public void FunctionWithDelegateParams(Action<string> action)
        {
            action("string value");
        }

    }


    public class SampleEventArgs
    {
        public SampleEventArgs(string text) { Text = text; }
        public string Text { get; } // readonly
    }

    //#csg013-11
    //event 关键字用于声明用于类需要发布的事件。
    //如果你的类需要发布事件来通知类的使用者并执行使用者指定代码,你就可以使用event关键字来声明一个委托变量作为类的事件。
    public class Publisher
    {
        //声明事件使用的委托类型
        public delegate void SampleEventHandler(object sender, SampleEventArgs e);

        //#csg013-12
        //声明一个事件
        public event SampleEventHandler SampleEvent;

        //#csg013-13
        //触发事件
        protected virtual void RaiseSampleEvent()
        {
            //触发事件,使用protected virtual 可让继承类可以触发事件
            SampleEvent?.Invoke(this, new SampleEventArgs("Hello"));
        }
    }


    //事件简单说明
    //事件委托的挂载
    public class UseEventDemo
    {
        public void F()
        {
            var publisher = new Publisher();

            //#csg013-14
            //使用 += 操作符为事件挂载方法
            //你可以为事件挂载多个委托,
            publisher.SampleEvent += Publisher_SampleEvent;


            //#csg013-15
            //使用 -= 操作符将挂载的方法移除
            publisher.SampleEvent -= Publisher_SampleEvent;

        }

        private void Publisher_SampleEvent(object sender, SampleEventArgs e)
        {
            throw new NotImplementedException();
        }
    }



}