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

前文:

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

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

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


範例解說:

宣告一個 voidDelegate 委託

1
2
3
4
5
6
7
8
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當作方法來使用

1
2
3
4
5
6
7
8
9
calcInt calcint = new calcInt(add);
var result1 = calcint(5,5);
Console.WriteLine(result1);

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

或是

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

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

編譯器會動態幫我們產生一個方法。

委託就這樣嗎?!


進階的用法

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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端決定如何使用此方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

原始碼範例

此文作者:Daniel Shih(石頭)
此文地址https://isdaniel.github.io/c-func-1/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!


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