1. 程式人生 > >C# 委托Delegate

C# 委托Delegate

res 不能 run 約束 nor img 我們 ted lov

一、委托是什麽

在微軟的文檔是這樣解釋的:在 .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;

C# 委托Delegate