C# 委托Delegate

一、委托是什么

在微软的文档是这样解释的:在 .NET 中委托提供后期绑定机制。 后期绑定意味着调用方在你所创建的算法中至少提供一个方法来实现算法的一部分。

在前面的学习中我们知道程序编译的过程中会编译为中间语言的过程,我们通过反编译看看。

    public delegate void NoReturnNoParaOutClass();
    public class MyDelegate //: System.MulticastDelegate
    {
        /// <summary>
        /// 1 委托在IL就是一个类
        /// 2 继承自System.MulticastDelegate 特殊类-不能被继承
        /// </summary>
        public delegate void NoReturnNoPara();
        public delegate void NoReturnWithPara(int x, int y);//1 声明委托
        public delegate int WithReturnNoPara();
        public delegate MyDelegate WithReturnWithPara(out int x, ref int y);
   }
C# 源码
.class public auto ansi sealed MyDelegateEvent.NoReturnNoParaOutClass
    extends [mscorlib]System.MulticastDelegate
{
    // Methods
    .method public hidebysig specialname rtspecialname 
        instance void .ctor (
            object 'object',
            native int 'method'
        ) runtime managed 
    {
    } // end of method NoReturnNoParaOutClass::.ctor

    .method public hidebysig newslot virtual 
        instance void Invoke () runtime managed 
    {
    } // end of method NoReturnNoParaOutClass::Invoke

    .method public hidebysig newslot virtual 
        instance class [mscorlib]System.IAsyncResult BeginInvoke (
            class [mscorlib]System.AsyncCallback callback,
            object 'object'
        ) runtime managed 
    {
    } // end of method NoReturnNoParaOutClass::BeginInvoke

    .method public hidebysig newslot virtual 
        instance void EndInvoke (
            class [mscorlib]System.IAsyncResult result
        ) runtime managed 
    {
    } // end of method NoReturnNoParaOutClass::EndInvoke

} // end of class MyDelegateEvent.NoReturnNoParaOutClass


.class public auto ansi beforefieldinit MyDelegateEvent.MyDelegate
    extends [mscorlib]System.Object
{
    // Nested Types
    .class nested public auto ansi sealed NoReturnNoPara
        extends [mscorlib]System.MulticastDelegate
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor (
                object 'object',
                native int 'method'
            ) runtime managed 
        {
        } // end of method NoReturnNoPara::.ctor

        .method public hidebysig newslot virtual 
            instance void Invoke () runtime managed 
        {
        } // end of method NoReturnNoPara::Invoke

        .method public hidebysig newslot virtual 
            instance class [mscorlib]System.IAsyncResult BeginInvoke (
                class [mscorlib]System.AsyncCallback callback,
                object 'object'
            ) runtime managed 
        {
        } // end of method NoReturnNoPara::BeginInvoke

        .method public hidebysig newslot virtual 
            instance void EndInvoke (
                class [mscorlib]System.IAsyncResult result
            ) runtime managed 
        {
        } // end of method NoReturnNoPara::EndInvoke

    } // end of class NoReturnNoPara

    .class nested public auto ansi sealed NoReturnWithPara
        extends [mscorlib]System.MulticastDelegate
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor (
                object 'object',
                native int 'method'
            ) runtime managed 
        {
        } // end of method NoReturnWithPara::.ctor

        .method public hidebysig newslot virtual 
            instance void Invoke (
                int32 x,
                int32 y
            ) runtime managed 
        {
        } // end of method NoReturnWithPara::Invoke

        .method public hidebysig newslot virtual 
            instance class [mscorlib]System.IAsyncResult BeginInvoke (
                int32 x,
                int32 y,
                class [mscorlib]System.AsyncCallback callback,
                object 'object'
            ) runtime managed 
        {
        } // end of method NoReturnWithPara::BeginInvoke

        .method public hidebysig newslot virtual 
            instance void EndInvoke (
                class [mscorlib]System.IAsyncResult result
            ) runtime managed 
        {
        } // end of method NoReturnWithPara::EndInvoke

    } // end of class NoReturnWithPara

    .class nested public auto ansi sealed WithReturnNoPara
        extends [mscorlib]System.MulticastDelegate
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor (
                object 'object',
                native int 'method'
            ) runtime managed 
        {
        } // end of method WithReturnNoPara::.ctor

        .method public hidebysig newslot virtual 
            instance int32 Invoke () runtime managed 
        {
        } // end of method WithReturnNoPara::Invoke

        .method public hidebysig newslot virtual 
            instance class [mscorlib]System.IAsyncResult BeginInvoke (
                class [mscorlib]System.AsyncCallback callback,
                object 'object'
            ) runtime managed 
        {
        } // end of method WithReturnNoPara::BeginInvoke

        .method public hidebysig newslot virtual 
            instance int32 EndInvoke (
                class [mscorlib]System.IAsyncResult result
            ) runtime managed 
        {
        } // end of method WithReturnNoPara::EndInvoke

    } // end of class WithReturnNoPara

    .class nested public auto ansi sealed WithReturnWithPara
        extends [mscorlib]System.MulticastDelegate
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor (
                object 'object',
                native int 'method'
            ) runtime managed 
        {
        } // end of method WithReturnWithPara::.ctor

        .method public hidebysig newslot virtual 
            instance class MyDelegateEvent.MyDelegate Invoke (
                [out] int32& x,
                int32& y
            ) runtime managed 
        {
        } // end of method WithReturnWithPara::Invoke

        .method public hidebysig newslot virtual 
            instance class [mscorlib]System.IAsyncResult BeginInvoke (
                [out] int32& x,
                int32& y,
                class [mscorlib]System.AsyncCallback callback,
                object 'object'
            ) runtime managed 
        {
        } // end of method WithReturnWithPara::BeginInvoke

        .method public hidebysig newslot virtual 
            instance class MyDelegateEvent.MyDelegate EndInvoke (
                [out] int32& x,
                int32& y,
                class [mscorlib]System.IAsyncResult result
            ) runtime managed 
        {
        } // end of method WithReturnWithPara::EndInvoke

    } // end of class WithReturnWithPara
} // end of class MyDelegateEvent.MyDelegate
反编译后的IL 代码

通过IL代码我们可以看到委托在IL就是一个类,继承自System.MulticastDelegate 特殊类-不能被继承。

二、委托语法

委托的声明:

        public delegate void NoReturnNoPara();
        public delegate void NoReturnWithPara(int x, int y);//1 声明委托
        public delegate int WithReturnNoPara();
        public delegate MyDelegate WithReturnWithPara(out int x, ref int y);
View Code

声明委托的实例:

     public class MyDelegate
    {
        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }
        private static void DoNothingStatic()
        {
            Console.WriteLine("This is DoNothingStatic");
        }
    }

    public class OtherClass
    {
        public void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }
        public static void DoNothingStatic()
        {
            Console.WriteLine("This is DoNothingStatic");
        }
    }
View Code

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

三、多播委托

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

四、委托的使用

//多种途径实例化,要求传递一个参数类型,返回值都跟委托一致的方法
{
   WithReturnWithPara method = new WithReturnWithPara(ParaReturn);
   int x = 0;
   int y = 0;
   var dd = method.Invoke(out x, ref y);
 }
//begininvoke
{
   WithReturnNoPara method = new WithReturnNoPara(new OtherClass().DoNothing);
   int iResult = method.Invoke();
   iResult = method();
   var result = method.BeginInvoke(null, null);//异步调用
   method.EndInvoke(result);
}
{
   NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
   //委托实力的调用,参数和委托约束的一致
    method.Invoke(); //1
    //method(); //2
    //method.BeginInvoke(null, null); //3
    //this.DoNothing(); //1,2,3都等同于this.DoNothing

}
{
     NoReturnNoPara method = new NoReturnNoPara(OtherClass.DoNothingStatic);
}
{
    NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);
}
{
    NoReturnNoPara method = new NoReturnNoPara(new Student().Study);
}
View Code

五、Action、Func

注意:其实框架已经我们帮我们定义了Action 和Func这两个委托,Action是没有返回值,Func是有返回值的,这两个委托类已经足够我们使用了,所以有时候我们使用的时候,没有必要自己再去定义,而直接使用即可;

1:Action: 系统提供的,0-16个泛型参数,不带返回值的 委托

Action act=()=>{};  Action act=o1=>{};Action act=(o1,o2,o3)=>{};...

2:Func 系统提供的,0-16个泛型参数,带一个返回值的 委托

Func func=()=>1;  Func func=x=>x;Func func=(x,y,z)=>x+y+z;...

 

本文参考文档:https://www.cnblogs.com/loverwangshan/p/10153171.html;

微软文档地址:

委托、事件:https://docs.microsoft.com/zh-cn/dotnet/csharp/delegates-events;

Action:https://docs.microsoft.com/zh-cn/dotnet/api/system.action?view=netframework-4.7.2;

Func:https://docs.microsoft.com/zh-cn/dotnet/api/system.func-1?view=netframework-4.7.2;

原文地址:https://www.cnblogs.com/Dewumu/p/10575806.html