感謝老師的教學視頻:C#语言入门详解(特辑001)
Delegate 己過時,進化成 Action、Func:
委派
delegate void MyDele();
泛型委派
delegate T MyDele<T>(T a, T b);
Action: 沒有返回值的委派,用於無回傳值的方法
Func: 有返回值的委派,用於有回傳值的方法1. 匿名方法
2. Inline 方法
使用時機:程式中若有很多的細算法(e .g.加減乘除),臨時算一下用完就沒了,就可以使用Lambda。
※ Inline code:將Function(函式)的內容直接以inline 的方式寫在一般的程式碼之中,省去另外定義Function。MSDN: https://msdn.microsoft.com/zh-tw/library/bb397687.aspx
[建立概念]
委派是什麼?
1. 類似C++函式指標的概念。
2. 像是一個方法的封裝器,一個函式或是一組函式的封裝器。
https://www.youtube.com/watch?v=g1EU9gnZKOg
模擬場景:
1. 小明最近學習情緒高漲,以前買的書已經滿足不了慾望,打算去買本(一個程序員的自我修養)。可是呢以前總是跑書廠買,太遠了扛不住,就去跑去附近書店去買,小明去給錢就弄了一本書回來,這個過程就是委託。
http://www.cnblogs.com/LipeiNet/p/4694225.html
2. 貓大叫一聲,所有的老鼠都開始逃跑,主人被驚醒。
程式要求:
(1). 要有聯動性,老鼠和主人的行為是被動的。
(2). 考慮可擴展性,貓的叫聲可能引發其他聯動效應。
http://www.programgo.com/article/24262282064/
[實作練習]
Delegate
1. 委派也是一種Class
2. 需要聲明
3. 參數類型要一致
Delegate(無返回值)
Example 1: 調用一個Function
class Program {
static void Main(string[] args) {
MyDele dele1 = new MyDele(M1);
dele1 += M1; //多重委派,就是用委派變數+= 方法名稱
dele1();
}
static void M1() {
Console.WriteLine("M1 is called.");
}
}
delegate void MyDele();
Example 2: 調用Class的Function
class Program {
static void Main(string[] args) {
MyDele dele1 = new MyDele(M1);
dele1 += new Student().SayHello; //調用Class的Function
dele1();
Console.Read();
}
static void M1() {
Console.WriteLine("M1 is called.");
}
}
class Student {
public void SayHello() {
Console.WriteLine("Hello, I'm Riva.");
}
}
delegate void MyDele();
Delegate(有返回值)
class Program {
static void Main(string[] args) {
MyDele dele = new MyDele(Add);
int result = dele(100, 200);
Console.WriteLine(result);
}
static int Add(int x, int y) {
return x + y;
}
}
delegate int MyDele(int a, int b);
Generics Delegates (泛型委派):
class Program {
static void Main(string[] args) {
MyDele<int> deleAdd = new MyDele<int>(Add);
int addResult = deleAdd(100, 200);
Console.WriteLine(addResult);
MyDele<double> deleMul = new MyDele<double>(Mul);
double mulResult = deleMul(3.0, 4.0);
Console.WriteLine(mulResult);
}
static int Add(int x,int y) {
return x = y;
}
static Double Mul(double x, double y) {
return x * y;
}
}
delegate T MyDele<T>(T a, T b);
class Program {
static void Main(string[] args) {
Action action = new Action(M1);
action();
}
static void M1() {
Console.WriteLine("M1 is called.");
}
}
Action (有參數)
class Program {
static void Main(string[] args) {
Action<string> action = new Action<string>(SayHello);
action("Riva");
}
static void SayHello(string name) {
Console.WriteLine("I'm {0}", name); //Console.WriteLine($"I'm {name}"); C# 6
}
}
Action (多參數,不同類型)
class Program {
static void Main(string[] args) {
var action = new Action<string, int>(SayHello);
action("Riva", 3);
}
static void SayHello(string name, int round) {
for (int i = 0; i < round; i++) {
Console.WriteLine("Hello, {0}", name);
}
}
}
Func: 有回傳值
Func (Int類型)
class Program {
static void Main(string[] args) {
Func<int, int, int> func = new Func<int, int, int>(Add);
int res = func(100, 200);
Console.WriteLine(res);
}
static int Add(int x, int y) {
return x = y;
}
class Program {
static void Main(string[] args) {
var func = new Func<double, double, double>(Mul);
double result = func(3.0, 4.0);
Console.WriteLine(result);
}
static Double Mul(double x, double y) {
return x * y;
}
Func + Lambda (泛型委派)
原始寫法:
class Program {
static void Main(string[] args) {
Func<int, int, int> func = new Func<int, int, int>((int a, int b) => { return a + b; });
int res = func(100,200);
Console.WriteLine(res);
func = new Func<int, int, int>((int x, int y) => { return x * y; });
res = func(3,4);
Console.WriteLine(res);
}
}
進一步簡化:(省略int)
class Program {
static void Main(string[] args) {
Func<int, int, int> func = new Func<int, int, int>((a, b) => { return a + b; });
int res = func(100, 200);
Console.WriteLine(res);
func = new Func<int, int, int>((x, y) => { return x * y; });
res = func(3, 4);
Console.WriteLine(res);
Console.Read();
}
}
再簡化:(直接賦值給委派參數Lambda表達式) ★★★★★
class Program {
static void Main(string[] args) {
Func<int, int, int> func = (a, b) => { return a + b; };
int res = func(100, 200);
Console.WriteLine(res);
func = (x, y) => { return x * y; };
res = func(3, 4);
Console.WriteLine(res);
}
}
泛型方法+泛型的委派參數+泛型參數 ★★★★★
(泛型函式的參數為"Func類型的參數")
原始寫法:
namespace Combine {
class Program {
static void Main(string[] args) {
DoSomeCalc<int>((int a, int b) => { return a * b; }, 100, 200);
Console.Read();
}
static void DoSomeCalc<T>(Func<T,T,T> func, T x, T y) {
T res= func(x, y);
Console.WriteLine(res);
}
}
省略int
class Program {
static void Main(string[] args) {
DoSomeCalc((a, b) => { return a * b; }, 100, 200);
}
static void DoSomeCalc<T>(Func<T, T, T> func, T x, T y) {
T res = func(x, y);
Console.WriteLine(res);
}
}
Ref:
1. C#语言入门详解(特辑001) ★★★★★
2. C#的委派與事件的使用:
3. [C#] 快速了解泛型委派:
4. 設計模式面試與筆試題剖析(二)
5. C#之Action和Func的用法
6. C# IN DEPTH