一,聲明委托
對于委托,定義它就是要告訴編譯器,這種類型的委托表示哪種類型的方法.然后,必須創建該委托的一個或多個委托實例,編譯器將在后臺創建表示該委托的一個類.
因為定義委托基本上是定義一個新類,所以可以在定義類的任何相同地方定義委托.
在 術語 方面,和"類,對象"不同."類"表示的是較為廣義的定義,"對象"表示類的實例.但是委托只有一個術語,在創建委托實例時,所創建的 委托的實例 仍然稱為 委托 .
如下顯示委托的聲明方式:
//聲明委托.
private delegate string GetAString();
?
二,使用委托
如下例子:
1
int
x =
5
;
2
//
通過委托的方式.
3
GetAString stringMethod =
new
GetAString(x.ToString);
4
Console.WriteLine(stringMethod());
也可以使用 委托推斷 ,只需將地址傳遞給委托類型的變量(在后臺,C#編譯器會做同樣的處理,即會在后臺創建一個委托實例 " new GetAString(x.ToString)"):
1
//
使用委托推斷,只需將地址傳遞給委托實例.
2 GetAString secondMethod = x.ToString;
實際上,調用委托時,給委托實例提供圓括號與調用委托的Invoke()方法,是完全相同的:
1
Console.WriteLine(stringMethod());
//
委托方式1(使用圓括號的方式).
2
Console.WriteLine(stringMethod.Invoke());
//
委托方式2(使用調用Invoke()方法的方式).
原因是對于委托變量stringMethod,C#編譯器會調用stringMethod.Invoke()代替stringMethod().
值得注意的是,在給一個委托類型的變量賦值的時候,方法的名稱不能帶有"()"括號,上述例子,調用 x.ToString()方法,會返回一個不能賦予委托變量的字符串對象(而不是方法的地址).
委托的一個特征是,它們是類型安全的,可以確定被調用的方法的簽名是正確的.但是委托不關心在什么類型上調用改方法,甚至不考慮方法是靜態的,還是實例方法.
如下例子演示了委托可以使用實例方法,也可以使用靜態方法:
Currency結構的聲明:
1
namespace
Wrox.ProCSharp.Delegates {
2
struct
Currency {
3
public
uint
Dollars;
4
public
ushort
Cents;
5
6
public
Currency(
uint
dollars,
ushort
cents) {
7
this
.Dollars =
dollars;
8
this
.Cents =
cents;
9
}
10
11
public
override
string
ToString() {
12
return
string
.Format(
"
${0}.{1,-2:00}
"
, Dollars, Cents);
13
}
14
15
public
static
string
GetCurrencyUnit() {
16
return
"
Dollar
"
;
17
}
18
19
public
static
explicit
operator
Currency(
float
value) {
20
checked
{
21
uint
dollars = (
uint
)value;
22
ushort
cents = (
ushort
)((value - dollars) *
100
);
23
return
new
Currency(dollars, cents);
24
}
25
}
26
27
public
static
implicit
operator
float
(Currency value) {
28
return
value.Dollars + (value.Cents /
100.0f
);
29
}
30
31
public
static
implicit
operator
Currency(
uint
value) {
32
return
new
Currency(value,
0
);
33
}
34
35
public
static
implicit
operator
uint
(Currency value) {
36
return
value.Dollars;
37
}
38
}
39
40
}
在住函數中調用:
1
using
System;
2
3
namespace
Wrox.ProCSharp.Delegates
4
{
5
class
Program
6
{
7
private
delegate
string
GetAString();
8
9
static
void
Main()
10
{
11
int
x =
40
;
12
GetAString firstStringMethod =
x.ToString;
13
Console.WriteLine(
"
String is {0}
"
, firstStringMethod());
14
15
Currency balance =
new
Currency(
34
,
50
);
16
17
//
firstStringMethod references an instance method
18
firstStringMethod =
balance.ToString;
19
Console.WriteLine(
"
String is {0}
"
, firstStringMethod());
20
21
//
firstStringMethod references a static method
22
firstStringMethod =
new
GetAString(Currency.GetCurrencyUnit);
23
Console.WriteLine(
"
String is {0}
"
, firstStringMethod());
24
25
}
26
}
27
}
? 輸出:
String
is
40
String
is
$
34.50
String
is
Dollar
? 再來看一個委托使用:
定義操作的方法的類:
1
namespace
SimpleDelegates_Demo {
2
class
MathOperations {
3
public
static
double
MultiplyByTwo(
double
value) {
4
return
value *
2
;
5
}
6
7
public
static
double
Square(
double
value) {
8
return
value *
value;
9
}
10
}
11
12
}
在主函數中使用:
1
using
System;
2
3
namespace
SimpleDelegates_Demo {
4
delegate
double
Operate(
double
input);
5
class
Program {
6
static
void
Main(
string
[] args) {
7
Operate[] actions =
{ MathOperations.MultiplyByTwo, MathOperations.Square };
8
//
遍歷每個委托實例.
9
foreach
(Operate action
in
actions) {
10
ProcessAndDisplayResult(action,
2
);
11
ProcessAndDisplayResult(action,
2.5
);
12
ProcessAndDisplayResult(action,
5.2
);
13
Console.WriteLine();
14
}
15
}
16
17
static
void
ProcessAndDisplayResult(Operate action,
double
inputVal) {
18
Console.WriteLine(
"
Input is [{0}],Result is [{1}]
"
, inputVal, action(inputVal));
19
}
20
}
21
}
output:
1
Input
is
[
2
],Result
is
[
4
]
2
Input
is
[
2.5
],Result
is
[
5
]
3
Input
is
[
5.2
],Result
is
[
10.4
]
4
5
Input
is
[
2
],Result
is
[
4
]
6
Input
is
[
2.5
],Result
is
[
6.25
]
7
Input
is
[
5.2
],Result
is
[
27.04
]
在這個例子中,我們將委托實例封裝到一個數組中,然后遍歷每個委托實例,然后傳遞遍歷到特定的方法中調用,這說明使用委托的一種方式 - 即把方法組合到一個數組中來使用,這樣就可以在循環中調用不同的方法了.
值得注意的是,這里 ProcessAndDisplayResult(Operate action, double inputVal) 不是多余的.
當我們在主函數的第10~12行中傳遞action委托實例到 ProcessAndDisplayResult(Operate action, double inputVal) 方法的時候,
action就是
委托表示的方法.
而在ProcessAndDisplayResult(Operate action, double inputVal)方法體中,也就是上面Program類中的第18行中的action(inputVal),或action(2)實際上調用這個方法,參數放在圓括號中.也就是說, action(inputVal),或action(2) 實際上是調用action委托實例封裝的方法.
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

