C# 委托Delegate
一、委托是什麽
在微軟的文檔是這樣解釋的:在 .NET 中委托提供後期綁定機制。 後期綁定意味著調用方在你所創建的算法中至少提供一個方法來實現算法的一部分。
在前面的學習中我們知道程序編譯的過程中會編譯為中間語言的過程,我們通過反編譯看看。
public delegate void NoReturnNoParaOutClass(); public class MyDelegate //: System.MulticastDelegate { /// <summary> /// 1 委托在IL就是一個類C# 源碼/// 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, refint y); }
.class public auto ansi sealed MyDelegateEvent.NoReturnNoParaOutClass extends [mscorlib]System.MulticastDelegate { // Methods .method public hidebysig specialname rtspecialname instance void .ctor ( object ‘object‘, native反編譯後的IL 代碼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就是一個類,繼承自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