本系列文章將詳細探討C#中的委托,列舉其主要的實現方式,並分析其在設計層面和編碼層面帶來的好處,最後會討論其安全性和執行效率等。 什麼是委托? 委托是尋址方法的.NET版本,使用委托可以將方法作為參數進行傳遞。委托是一種特殊類型的對象,其特殊之處在於委托中包含的只是一個活多個方法的地址,而不是數據。 委托雖然看起來像是一種類型,但其實定義一個委托,是定義了一個新的類。下面這行代碼,定義了一個委托,使用ILDasm.exe查看其生成的IL代碼如圖所示: //定義委托,它定義了可以代表的方法的類型,但其本身卻是一個類 public delegate int methodDelegate(string str); 032101 由圖中紅色框線中可以看出,.NET將委托定義為一個密封類,派生自基類System.MulticastDelegate,並繼承了基類的三個方法(稍後討論這三個)。 委托與函數指針的區別 1、安全性:C/C++的函數指針只是提取了函數的地址,並作為一個參數傳遞它,沒有類型安全性,可以把任何函數傳遞給需要函數指針的地方;而.NET中的委托是類型安全的。 2、與實例的關聯性:在面向對象編程中,幾乎沒有方法是孤立存在的,而是在調用方法前通常需要與類實例相關聯。委托可以獲取到類實例中的信息,從而實現與實例的關聯。 3、本質上函數指針是一個指針變量,分配在棧中;委托類型聲明的是一個類,實例化為一個對象,分配在堆中。 4、委托可以指向不同類中具有相同參數和簽名的函數,函數指針則不可以。 復制代碼 namespace ConsoleApplication1 { //定義委托,它定義了可以代表的方法的類型,但其本身卻是一個類 public delegate void methodDelegate(string str); class Program { static void Main(string[] args) { Student student = new Student(); Teacher teacher = new Teacher("王老師"); methodDelegate methodDelegate1 = new methodDelegate(student.getStudentName); methodDelegate1 += teacher.getTeacherName; //可以指向不同類中的方法! //methodDelegate1 += teacher.getClassName; 指向簽名不符的方法時提示錯誤! methodDelegate1.Invoke("張三"); Console.ReadLine(); } } class Student { private String name = ""; public Student (String _name) { this.name = _name ; } public Student() {} public void getStudentName(String _name) { if (this.name != "" ) Console.WriteLine("Student's name is {0}", this.name); else Console.WriteLine("Student's name is {0}", _name); } } class Teacher { private String name; public Teacher(String _name) { this.name = _name; } public void getTeacherName(String _name) { if (this.name != "") Console.WriteLine("Teacher's name is {0}", this.name); else Console.WriteLine("Teacher's name is {0}", _name); } public string getClassName() { return "Eanlish"; } } }