【C#】委託delegate,Func<>,Action 解說系列(一)

  • 5242
  • 0
  • c#
  • 2018-01-09

成為.Net高手Delegate 是必備武器之一

今天小弟和大家分享我所認知的Delegate

 一開始我們先來看看Delegate到底是不是類別

宣告一個 voidDelegate 委託

public delegate void voidDelegate();

static void Main(string[] args)
{
    Console.WriteLine($"delegate is class? {typeof(voidDelegate).IsClass}");

    Console.ReadKey();
}

執行結果:Yes 委託是一個特別的類別

但委託物件方式很特別 他在宣告時必須傳入[建構子參數]  而建構子參數是[方法]

 

我們宣告一個委託 傳入兩個Int參數 回傳Int

public delegate int calcInt(int arg1,int arg2);

使用如下 new 一個 calcInt 並傳入建構子參數  add方法 之後就可以把calcint當作方法來使用

calcInt calcint = new calcInt(add);
var result1 = calcint(5,5);
Console.WriteLine(result1);


//方法
static int add(int a, int b)
{
    return a + b;
}

或是~

使用.net提供的 語法糖 如下

calcInt calcint1 = (a,b) => { return a + b; };
var result2 = calcint1(5, 5);
Console.WriteLine(result2);

(a,b) => { return a + b; }; 編譯器會動態幫我們產生一個方法。

委託就這樣嗎?!

 

來點進階的用法XD

 

第一 : 宣告一個類別[計算者],建構子參數是一個泛行List<T>

在類別中宣告Calc委託,在Excute方法中我們直接回傳執行Calc結果

public class Calculator<T>
    where T : struct
{
    public delegate T Calc(IList<T> list);

    IList<T> _container;
    public Calculator(IList<T> container)
    {
        _container = container;
    }
    public T Excute(Calc C)
    {
        return C(_container);
    }
}

 

使用方法如下:

宣告一個物件Calculator傳入建構子參數List

重點:我們可以在Client端決定如何使用此方法

List<int> i_List = new List<int>()
{
    1,3,5,7,9
};
Calculator<int> calculator = new Calculator<int>(i_List);
int i_add = calculator.Excute((list) => list.Sum());
int i_multi = calculator.Excute((list) =>
{
    int totle = 1;
    foreach (var i in list)
    {
        totle *= i;
    }
    return totle;
});
Console.WriteLine($"add:{i_add}  multi:{i_multi}");

總結:如上面程式碼 我們可在Client中決定對List集合做操作(加,減,乘,除) ,而不是一開始就寫死在類別中,降低了類別方法和Client的耦合

Delegate可以把方法實作的權利移交給Clinet端

範例原始碼 


如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^