c#委託

Nincems發表於2018-11-18

轉自:https://www.cnblogs.com/dotnet261010/p/6052829.html

1、什麼是委託

從資料結構來講,委託是和類一樣是一種使用者自定義型別。

委託是方法的抽象,它儲存的就是一系列具有相同簽名和返回回型別的方法的地址。呼叫委託的時候,委託包含的所有方法將被執行。

2、委託的定義

委託是型別,就好像類是型別一樣。與類一樣,委託型別必須在被用來建立變數以及型別物件之前宣告。

委託的宣告原型是 delegate <函式返回型別> <委託名> (<函式引數>)

例子:public delegate void MyDelegate(int number);//定義了一個委託MyDelegate,它可以註冊返回void型別且有一個int作為引數的函式

3、委託的例項化

3.1 使用new關鍵字

委託例項化的原型是 <委託型別> <例項化名>=new <委託型別>(<註冊函式>) 例子:MyDelegate _MyDelegate=new MyDelegate(CheckMod);//用函式CheckMod例項化上面的MyDelegate 委託為_MyDelegate

3.2 使用匿名方法

<委託型別> <例項化名>=delegate(<函式引數>){函式體};

3.3 使用Lambda表示式

class Program
{
    //宣告委託
    delegate int MyDelegate(int x, int y);

    static void Main(string[] args)
    {
        //例項化委託
        //1、使用new關鍵字
        MyDelegate _myDelegate = new MyDelegate(GetSum);

        //2、使用匿名方法
        MyDelegate myDelegate = delegate(int x, int y)
        {
            return x + y;
        };

        //3、使用Lambda表示式
        MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
    }

    static int GetSum(int x, int y)
    {
        return x + y;
    }
}

4、泛型委託

委託也支援泛型的使用 泛型委託原型: delegate <委託名> (T1 t1,T2 t2,T3 t3...)

例如:delegate T2 DelegateDemo(T1 t);//定義有兩個泛型(T1,T2)的委託,T2作為委託函式返回型別,T1作為委託函式引數型別

static boo Check(int i) { if(i%2==0)

{

return true;

}

return false;

}

static void Main(string[] args) { DelegateDemo _delegate =Check;//將泛型委託委託例項化為,即表示有一個int型別引數且返回型別是bool的函式. Console.WriteLine(_delegate(9));//false }

5、C#內建泛型委託

C#共有3種內建泛型委託

namespace DelegateDemo
{
class Program
{
    //宣告委託
    delegate int MyDelegate(int x, int y);

    static void Main(string[] args)
    {
        //1、Action<T>只能委託必須是無返回值的方法
        Action<string> _action = new Action<string>(SayHello);
        _action("Hello World");

        //2、Fun<TResult>只是委託必須有返回值的方法
        Func<int, bool> _func = new Func<int, bool>(Check);
        _func(5);

        //3、Predicate:此委託返回一個bool值,該委託通常引用一個"判斷條件函式"。
        //需要指出的是,判斷條件一般為“外部的硬性條件”,比如“大於50”,而不是由資料自身指定,如“查詢陣列中最大的元素就不適合”。
        Predicate<int> _predicate = new Predicate<int>(Check);
        //使用Lambda表示式
        Predicate<int> predicate = p => p % 2 == 0;
        _predicate(26);
    }

    static void SayHello(string strMsg)
    {
        Console.WriteLine(strMsg);
    }

    //返回值為bool值
    static bool Check(int i)
    {
        if (i % 2 == 0)
        {
            return true;
        }
        return false;
    }       
}
}

6、多播委託

例項化委託時必須將一個匹配函式註冊到委託上來例項化一個委託物件,但是一個例項化委託不僅可以註冊一個函式還可以註冊多個函式,註冊多個函式後,在執行委託的時候會根據註冊函式的註冊先後順序依次執行每一個註冊函式。

函式註冊委託的原型: <委託型別> <例項化名>+=new <委託型別>(<註冊函式>) 例如:MyDelegate _myDelegate+=new MyDelegate(CheckMod);//將函式CheckMod註冊到委託例項_checkDelegate上 在.net 2.0開始可以直接將匹配的函式註冊到例項化委託: <委託型別> <例項化名>+=<註冊函式> 例如:MyDelegate _myDelegate+=CheckMod;//將函式CheckMod註冊到委託例項_myDelegate上

注意:委託必須先例項化以後,才能使用+=註冊其他方法。如果對註冊了函式的委託例項從新使用=號賦值,相當於是重新例項化了委託,之前在上面註冊的函式和委託例項之間也不再產生任何關係。

有+=註冊函式到委託,也有-=解除註冊

例如:MyDelegate _myDelegate-=CheckMod;

如果在委託註冊了多個函式後,如果委託有返回值,那麼呼叫委託時,返回的將是最後一個註冊函式的返回值。

namespace DelegateDemo
{
class Program
{
    //宣告委託
    delegate int MyDelegate(int x, int y);

    static void Main(string[] args)
    {
        MyDelegate _myDelegate = new MyDelegate(fun1);
        _myDelegate += fun2;
        Console.WriteLine(_myDelegate(10,23));

        Console.ReadKey();//輸出10,返回最後一個註冊函式的返回值
    }

    static int fun1(int x, int y)
    {
        return x + y;
    }

    static int fun2(int x, int y)
    {
        return x;
    }      
}
}

原文請見:https://www.cnblogs.com/dotnet261010/p/6052829.html

相關文章