C#委托詳解(1):什么是委托


本系列文章將詳細探討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";
        }
    }
}

上述測試代碼運行結果如下:

當指向簽名不符的方法時會提示如下錯誤,證實了委托的安全性。

本篇結束,下一篇介紹委托的主要實現方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2024 CODEPRJ.COM