C# Delegate 委托(上)

Delegate(委托):

C# 中的委托(Delegate)類似 C++ 中的 Function Pointer。 常用於事件和回調方法。所有的委托(Delegate)都衍生自 System.Delegate

1. 宣告委託:

delegate void IntMethodInvoker(int x); 

宣告時需包含回傳和引入之型別。

也可以使用訪問修飾符例如:

public delegate void IntMethodInvoker(int x); 

2. 委託的使用:

using System;

namespace DotNetCoreTest
{
    class Program
    {
        // 宣告委托
        public delegate void Greeting();

        public static void Hello()
        {
            Console.WriteLine("Hello");
        }

        static void Main(string[] args)
        {
            // 用 Hello 實體化 Greet
            Greeting Greet = new Greeting(Hello);
            Greet();
            Greet.Invoke();
        }
    }
}

執行結果:

Hello
Hello

呼叫 Greet() 等同於呼叫 Greet.Invoke()


3. Func<T> 和 Action<T> 委托:

Func<T>委托用於委托有回傳值的方法,Action<T> 委托用於委托無回傳值的方法

Action<T>委托的用法:

using System;

namespace DotNetCoreTest
{
    class Program
    {
        
        public static void Hello (string name)
        {
            Console.WriteLine($"Hello {name}");
        }

        static void Main(string[] args)
        {
            Action<string> Greet = Hello;
            Greet("Bob");
            Greet.Invoke("Alice");
        }
    }
}

Func<T>委托的用法:

using System;

namespace DotNetCoreTest
{
    class Program
    {
        
        public static int DoubleNum (int num)
        {
            return 2 * num;
        }

        static void Main(string[] args)
        {
            Func<int, int> DN = DoubleNum;
            Console.WriteLine($"{DN (20)}");
            Console.WriteLine($"{DN.Invoke (20)}");
        }
    }
}

4. Func<T> 委托陣列:

Func<T> 和 Action<T> 可以衍伸出一些奇怪的寫法例如委托陣列:

using System;

namespace DotNetCoreTest
{
    class Program
    {

        public static int DoubleNum(int num) 
        {
            return 2 * num;
        }

        public static int AddOne(int num)
        {
            return num + 1;
        }

        static void Main(string[] args)
        {
            Func<int, int>[] MathOps = { DoubleNum, AddOne };

            Console.WriteLine(MathOps[0](10));
            Console.WriteLine(MathOps[1](10));
        }
    }
}

5. Func<T> 委托作為參數:

這應該是目前最實用的功能

using System;

namespace DotNetCoreTest
{
    class Program
    {

        public static int DoubleNum(int num) 
        {
            return 2 * num;
        }

        public static int DoSomeMath(Func<int, int>MathOp,
                                     int num)
        {
            return MathOp(num);
        }

        static void Main(string[] args)
        {
           Console.WriteLine($"{DoSomeMath(DoubleNum, 10)}");
        }
    }
}

!!! 6. 多播委托: !!!

這應該是最值得注意的功能,我們能用 "+" 號來合併多個委托、"-" 號來刪除委托。 呼叫多播委托時會將參數一一傳播給多個委托:

using System;

namespace DotNetCoreTest
{
    class Program
    {

        public static void Hello(string name) 
        {
            Console.WriteLine($"Hello {name}"); 
        }

        public static void Hi (string name)
        {
            Console.WriteLine($"Hi {name}");
        }

        static void Main(string[] args)
        {
            Action<string> Greet = Hello;
            Greet += Hi;

            Greet("Bob");
        }
    }
}

執行結果如下:

Hello Bob
Hi Bob

!!! 呼叫多播委托時的注意事項: !!!

  1. 調用方法的順序和添加的順序無關
  2. 其中一的方法發生異常時會造成迭代停止

留言

熱門文章