C#委托类似于C或C+中指向函数的指针,委托是保存对方法的引用类型变量,可以在运行时更改引用。
委托特别用于实现事件和回调方法,所有委托都隐式派生自System.Delegate类。
声明委托
委托声明确定委托可以引用的方法,委托可以引用与委托具有相同签名的方法。
public delegate int MyDelegate (string s);
前面的委托可用于引用具有单个string参数并返回int类型变量的任何方法。
委托声明的语法为-
delegate <return type> <delegate-name> <parameter list>
初始化委托
声明委托类型后,必须使用new关键字创建委托对象并与特定方法关联。创建委托时,传递给new表达式的参数编写与方法调用类似但没有方法的参数。
public delegate void printString(string s); ... printString ps1=new printString(WriteToScreen); printString ps2=new printString(WriteToFile);
下面的示例演示了委托的声明、实例化和使用该委托可用于引用接受整数参数并返回整数值的方法。
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">AddNum</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> p</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
num </span><span class="pun">+=</span><span class="pln"> p</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">MultNum</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> q</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
num </span><span class="pun">*=</span><span class="pln"> q</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> getNum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">Main</span><span class="pun">(</span><span class="kwd">string</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="com">//create delegate instances</span><span class="pln">
</span><span class="typ">NumberChanger</span><span class="pln"> nc1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">NumberChanger</span><span class="pun">(</span><span class="typ">AddNum</span><span class="pun">);</span><span class="pln">
</span><span class="typ">NumberChanger</span><span class="pln"> nc2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">NumberChanger</span><span class="pun">(</span><span class="typ">MultNum</span><span class="pun">);</span><span class="pln">
</span><span class="com">//使用委托对象调用方法</span><span class="pln">
nc1</span><span class="pun">(</span><span class="lit">25</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">WriteLine</span><span class="pun">(</span><span class="str">"Value of Num: {0}"</span><span class="pun">,</span><span class="pln"> getNum</span><span class="pun">());</span><span class="pln">
nc2</span><span class="pun">(</span><span class="lit">5</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">WriteLine</span><span class="pun">(</span><span class="str">"Value of Num: {0}"</span><span class="pun">,</span><span class="pln"> getNum</span><span class="pun">());</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">ReadKey</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
}
}
编译并执行上述代码时,将生成以下输出-
Value of Num: 35 Value of Num: 175
委托组播
可以使用“ +”运算符来组成委托对象,只能组成相同类型的代表。“-”运算符可用于从组合委托中删除组件委托。
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">AddNum</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> p</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
num </span><span class="pun">+=</span><span class="pln"> p</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">MultNum</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> q</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
num </span><span class="pun">*=</span><span class="pln"> q</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> getNum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> num</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">Main</span><span class="pun">(</span><span class="kwd">string</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="com">//create delegate instances</span><span class="pln">
</span><span class="typ">NumberChanger</span><span class="pln"> nc</span><span class="pun">;</span><span class="pln">
</span><span class="typ">NumberChanger</span><span class="pln"> nc1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">NumberChanger</span><span class="pun">(</span><span class="typ">AddNum</span><span class="pun">);</span><span class="pln">
</span><span class="typ">NumberChanger</span><span class="pln"> nc2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">NumberChanger</span><span class="pun">(</span><span class="typ">MultNum</span><span class="pun">);</span><span class="pln">
nc </span><span class="pun">=</span><span class="pln"> nc1</span><span class="pun">;</span><span class="pln">
nc </span><span class="pun">+=</span><span class="pln"> nc2</span><span class="pun">;</span><span class="pln">
</span><span class="com">//calling multicast</span><span class="pln">
nc</span><span class="pun">(</span><span class="lit">5</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">WriteLine</span><span class="pun">(</span><span class="str">"Value of Num: {0}"</span><span class="pun">,</span><span class="pln"> getNum</span><span class="pun">());</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">ReadKey</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
}
}
编译并执行上述代码时,将生成以下输出-
Value of Num: 75
使用委托
下面的示例演示了委托的用法,委托printString可用于引用接受字符串作为输入但不返回任何内容的方法。
无涯教程使用此委托调用两个方法,第一个方法将字符串打印到控制台,第二个方法将其打印到文件-
using System;
using System.IO;
namespace DelegateAppl {
class PrintString {
static FileStream fs;
static StreamWriter sw;
</span><span class="com">//delegate declaration</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">delegate</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> printString</span><span class="pun">(</span><span class="kwd">string</span><span class="pln"> s</span><span class="pun">);</span><span class="pln">
</span><span class="com">//此方法打印到控制台</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">WriteToScreen</span><span class="pun">(</span><span class="kwd">string</span><span class="pln"> str</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">WriteLine</span><span class="pun">(</span><span class="str">"The String is: {0}"</span><span class="pun">,</span><span class="pln"> str</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="com">//此方法打印到文件</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">WriteToFile</span><span class="pun">(</span><span class="kwd">string</span><span class="pln"> s</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
fs </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FileStream</span><span class="pun">(</span><span class="str">"c:\\message.txt"</span><span class="pun">,</span><span class="pln">
</span><span class="typ">FileMode</span><span class="pun">.</span><span class="typ">Append</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FileAccess</span><span class="pun">.</span><span class="typ">Write</span><span class="pun">);</span><span class="pln">
sw </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StreamWriter</span><span class="pun">(</span><span class="pln">fs</span><span class="pun">);</span><span class="pln">
sw</span><span class="pun">.</span><span class="typ">WriteLine</span><span class="pun">(</span><span class="pln">s</span><span class="pun">);</span><span class="pln">
sw</span><span class="pun">.</span><span class="typ">Flush</span><span class="pun">();</span><span class="pln">
sw</span><span class="pun">.</span><span class="typ">Close</span><span class="pun">();</span><span class="pln">
fs</span><span class="pun">.</span><span class="typ">Close</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="com">//此方法将委托作为参数并将其用于根据需要调用方法</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> sendString</span><span class="pun">(</span><span class="pln">printString ps</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
ps</span><span class="pun">(</span><span class="str">"Hello World"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">Main</span><span class="pun">(</span><span class="kwd">string</span><span class="pun">[]</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
printString ps1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> printString</span><span class="pun">(</span><span class="typ">WriteToScreen</span><span class="pun">);</span><span class="pln">
printString ps2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> printString</span><span class="pun">(</span><span class="typ">WriteToFile</span><span class="pun">);</span><span class="pln">
sendString</span><span class="pun">(</span><span class="pln">ps1</span><span class="pun">);</span><span class="pln">
sendString</span><span class="pun">(</span><span class="pln">ps2</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Console</span><span class="pun">.</span><span class="typ">ReadKey</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
}
}
编译并执行上述代码时,将生成以下输出-
The String is: Hello World