欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c#委托詳解和和示例分享

 更新時(shí)間:2014年03月23日 12:09:49   作者:  
這篇文章詳細(xì)探討了C#中的委托,列舉其主要的實(shí)現(xiàn)方式,并分析其在設(shè)計(jì)層面和編碼層面帶來的好處,最后會(huì)討論其安全性和執(zhí)行效率等,當(dāng)然還有實(shí)現(xiàn)示例
什么是委托?

委托是尋址方法的.NET版本,使用委托可以將方法作為參數(shù)進(jìn)行傳遞。委托是一種特殊類型的對(duì)象,其特殊之處在于委托中包含的只是一個(gè)活多個(gè)方法的地址,而不是數(shù)據(jù)。

委托雖然看起來像是一種類型,但其實(shí)定義一個(gè)委托,是定義了一個(gè)新的類。下面這行代碼,定義了一個(gè)委托,使用ILDasm.exe查看其生成的IL代碼如圖所示:

復(fù)制代碼 代碼如下:

//定義委托,它定義了可以代表的方法的類型,但其本身卻是一個(gè)類
 public delegate int methodDelegate(string str);

032101

由圖中紅色框線中可以看出,.NET將委托定義為一個(gè)密封類,派生自基類System.MulticastDelegate,并繼承了基類的三個(gè)方法(稍后討論這三個(gè))。

委托與函數(shù)指針的區(qū)別

1、安全性:C/C++的函數(shù)指針只是提取了函數(shù)的地址,并作為一個(gè)參數(shù)傳遞它,沒有類型安全性,可以把任何函數(shù)傳遞給需要函數(shù)指針的地方;而.NET中的委托是類型安全的。

2、與實(shí)例的關(guān)聯(lián)性:在面向?qū)ο缶幊讨校瑤缀鯖]有方法是孤立存在的,而是在調(diào)用方法前通常需要與類實(shí)例相關(guān)聯(lián)。委托可以獲取到類實(shí)例中的信息,從而實(shí)現(xiàn)與實(shí)例的關(guān)聯(lián)。

3、本質(zhì)上函數(shù)指針是一個(gè)指針變量,分配在棧中;委托類型聲明的是一個(gè)類,實(shí)例化為一個(gè)對(duì)象,分配在堆中。

4、委托可以指向不同類中具有相同參數(shù)和簽名的函數(shù),函數(shù)指針則不可以。

復(fù)制代碼 代碼如下:

namespace ConsoleApplication1
{
    //定義委托,它定義了可以代表的方法的類型,但其本身卻是一個(gè)類
    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; 指向簽名不符的方法時(shí)提示錯(cuò)誤!
            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";
        }
    }
}

上述測(cè)試代碼運(yùn)行結(jié)果如下:

當(dāng)指向簽名不符的方法時(shí)會(huì)提示如下錯(cuò)誤,證實(shí)了委托的安全性。

下面來看看C#中實(shí)現(xiàn)委托有哪些方式及各自主要適用范圍。

1、常規(guī)實(shí)現(xiàn)

復(fù)制代碼 代碼如下:

private delegate String getAString();
static void Main(String []args)
{
    int temp = 40;
    getAString stringMethod = new getAString(temp.ToString);
    Console.WriteLine("String is {0}", stringMethod());//這里stringMethod()等價(jià)于調(diào)用temp.ToString();
    Console.ReadLine();
}


這段代碼中,實(shí)例化了類型為GetAString的一個(gè)委托,并對(duì)它進(jìn)行初始化,使它引用整型變量temp的ToString()方法。在C#中,委托在語(yǔ)法上總是接受一個(gè)參數(shù)的構(gòu)造函數(shù),這個(gè)參數(shù)就是委托引用的方法。上例中stringMethod()等價(jià)于使用temp.ToString(),同時(shí)也與調(diào)用委托類的Invoke()方法完全相同,實(shí)際上,如下圖IL代碼中紅色部分所示,C#編譯器會(huì)用stringMethod.Invoke()代替stringMethod()。

為了簡(jiǎn)便輸入,C#支持只傳送地址的名稱給委托的實(shí)例(委托推斷),如下兩行代碼在編譯器看來是一樣的。

復(fù)制代碼 代碼如下:

getAString stringMethod = new getAString(temp.ToString);
getAString stringMethod = temp.ToString;

實(shí)際上委托的實(shí)例可以引用任何類型的任何對(duì)象上的實(shí)例方法或靜態(tài)方法,只要方法的簽名匹配于委托的簽名即可。所以結(jié)構(gòu)體的方法一樣可以傳遞給委托。

2、多播委托
多播委托具有一個(gè)帶有鏈接的委托列表,稱為調(diào)用列表,在對(duì)委托實(shí)例進(jìn)行調(diào)用的時(shí)候,將按列表中的委托順序進(jìn)行同步調(diào)用。如果委托有返回值,則將列表中最后一個(gè)方法的返回值用作整個(gè)委托調(diào)用的返回值。因此,使用多播委托通常具有void返回類型。

可以使用+=來使委托指向多個(gè)方法的地址,但必須是在委托實(shí)例化之后才可以使用+=來添加新的方法地址(添加重復(fù)的方法地址編譯器不會(huì)報(bào)錯(cuò),但是也不會(huì)重復(fù)執(zhí)行),若想移除其中的方法地址可以使用-=來實(shí)現(xiàn)(需要至少保留一個(gè),即對(duì)于最后一個(gè)方法地址的移除不起作用)。以下代碼中下面兩行無論單獨(dú)保留哪行,最終的執(zhí)行結(jié)果都是相同的。

復(fù)制代碼 代碼如下:

getAString stringMethod = new getAString(temp.ToString);
stringMethod += temp.ToString;
stringMethod -= temp.ToString;
 

3、委托數(shù)組

復(fù)制代碼 代碼如下:

delegate double Operations(double x);

    class Program
    {
static void Main()
{
    Operations[] operations =
    {
       MathOperations.MultiplyByTwo,
       MathOperations.Square
    };

    for (int i = 0; i < operations.Length; i++)
    {
Console.WriteLine("Using operations[{0}]:", i);
DisplayNumber(operations[i], 2.0);
DisplayNumber(operations[i], 7.94);
Console.ReadLine();
    }
}

static void DisplayNumber(Operations action, double value)
{
    double result = action(value);
    Console.WriteLine(
       "Input Value is {0}, result of operation is {1}", value, result);
}
    }

    struct MathOperations
    {
public static double MultiplyByTwo(double value)
{
    return value * 2;
}

public static double Square(double value)
{
    return value * value;
}
    }

上述代碼中實(shí)例化了一個(gè)委托數(shù)組operations(與處理類的實(shí)例相同),該數(shù)組的元素初始化為MathOperations類的不同操作,遍歷這個(gè)數(shù)組,可以將每個(gè)操作應(yīng)用到2個(gè)不同的值中。這種用法的好處是,可以在循環(huán)中調(diào)用不同的方法。

相關(guān)文章

  • C#中將ListView中數(shù)據(jù)導(dǎo)出到Excel的實(shí)例方法

    C#中將ListView中數(shù)據(jù)導(dǎo)出到Excel的實(shí)例方法

    首先 你需要添加引用Microsoft Excel 11.0 Object Library
    2013-04-04
  • c# BackgroundWorker使用方法

    c# BackgroundWorker使用方法

    這篇文章主要介紹了c# BackgroundWorker使用方法,文中代碼非常詳細(xì),幫助大家更好的參考學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • C# 實(shí)現(xiàn)Trim方法去除字符串前后的所有空格

    C# 實(shí)現(xiàn)Trim方法去除字符串前后的所有空格

    這篇文章主要介紹了C# 實(shí)現(xiàn)Trim方法去除字符串前后的所有空格,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 最好用的WPF加載動(dòng)畫功能

    最好用的WPF加載動(dòng)畫功能

    當(dāng)開發(fā)應(yīng)用程序時(shí),提供良好的用戶體驗(yàn)(UX)是至關(guān)重要的,加載動(dòng)畫作為一種有效的溝通工具,它不僅能告知用戶系統(tǒng)正在工作,還能夠通過視覺上的吸引力來增強(qiáng)整體用戶體驗(yàn),本文給大家介紹了最好用的WPF加載動(dòng)畫功能,需要的朋友可以參考下
    2025-01-01
  • C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的方法詳解

    C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的方法詳解

    這篇文章主要給大家介紹了關(guān)于C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • C#跨窗體操作(引用傳遞) 實(shí)例代碼

    C#跨窗體操作(引用傳遞) 實(shí)例代碼

    現(xiàn)在給大家介紹一種最簡(jiǎn)單的跨窗體操作,WinForm的窗體是一個(gè)類,C#的類是引用類型,那么我們應(yīng)該可以將WinForm窗體類進(jìn)行傳遞,那不就可以進(jìn)行操作了么?
    2013-03-03
  • C#解決文件被占用資源,無法刪除或修改的方法

    C#解決文件被占用資源,無法刪除或修改的方法

    這篇文章主要介紹C#解決文件被占用資源,比較實(shí)用,需要的朋友可以參考下。
    2016-06-06
  • 在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器

    在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器

    這篇文章主要介紹了在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問器的方法,是C#事件編程中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-02-02
  • 深入理解C#中常見的委托

    深入理解C#中常見的委托

    這篇文章主要介紹了C# 委托(Delegate)的相關(guān)資料,文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下,希望能夠幫助到你
    2021-07-07
  • C#實(shí)現(xiàn)異步操作的幾種方式

    C#實(shí)現(xiàn)異步操作的幾種方式

    在C#中,異步操作可以提高程序的性能和響應(yīng)能力,本文主要介紹了C#實(shí)現(xiàn)異步操作的幾種方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03

最新評(píng)論