C# Delegates 委托
声明委托
根据定义委托的可见性和委托的作用域,可以在委托的定义上应用任意常见的访问修饰符:public,private,protected。
使用委托
namespace Delegates {
class Program {
// 声明委托 private delegate string GetString(); static void Main(string[] args) {
// 定义一个委托的实例getString GetString getString = null; int i = 99; // 给委托赋值 getString = i.ToString; Console.WriteLine($"{getString()}"); } } }
在给委托赋值时,这个方法必须匹配委托声明时的签名,在调用时使用了类似方法的getString(),C#编译器会用getString.Invoke()代替getString()。
Action< T >和Func< T >委托
class Program {
private delegate double DoubleOp(double x); static void Main(string[] args) {
DoubleOp[] operations = {
MathOpertions.MuliplyByTwo,MathOpertions.Squate}; for(int i = 0; i < operations.Length; i++) {
ProcessAndDisplayNumble(operations[i], 2.0); ProcessAndDisplayNumble(operations[i], 7.94); ProcessAndDisplayNumble(operations[i], 1.414); } Console.WriteLine($""); } static void ProcessAndDisplayNumble(DoubleOp action, double value) {
double result = action(value); Console.WriteLine($"value={value},operation result ={result}"); } } class MathOpertions {
public static double MuliplyByTwo(double value) => value * 2; public static double Squate(double value) => value * value; }
上面列举了一个普通的委托实例,需要先声明一个委托,下面用Fun< double T , double T >修改上面的代码,不需要声明委托。
static void Main(string[] args) {
Func<double,double>[] operations = {
MathOpertions.MuliplyByTwo,MathOpertions.Squate}; for(int i = 0; i < operations.Length; i++) {
ProcessAndDisplayNumble(operations[i], 2.0); ProcessAndDisplayNumble(operations[i], 7.94); ProcessAndDisplayNumble(operations[i], 1.414); } Console.WriteLine($""); } static void ProcessAndDisplayNumble(Func<double, double> action, double value) {
double result = action(value); Console.WriteLine($"value={value},{action.ToString()} result ={result}"); } } class MathOpertions {
public static double MuliplyByTwo(double value) => value * 2; public static double Squate(double value) => value * value; }
多播委托
以上每个委托都只包含一个方法调用,调用委托的次数和调用 方法的次数相同。委托可以包含多个方法,如果调用多播委托,就会按照顺序连续调用多播委托中的方法。多播委托可以识别‘+’、‘+=’、‘-’、‘-=’。
class Program {
static void Main(string[] args) {
Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{
2.0, 7.94, 1.414 }; foreach(var item in arr) {
operations(item); } Console.WriteLine($"Hello World"); } } class MathOpertions {
public static void MuliplyByTwo(double value) {
double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); } public static void Square(double value) {
double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } }
使用多播委托会有一个问题:通过委托调用的其中一个方法抛出异常,整个迭代就会停止。如下代码所示,在方法中假装抛出异常:
class Program {
static void Main(string[] args) {
Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{
2.0, 7.94, 1.414 }; foreach(var item in arr) {
operations(item); } Console.WriteLine($"Hello World"); } } class MathOpertions {
public static void MuliplyByTwo(double value) {
double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) {
double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } }
解决这个问题:使用try…catch,抛出异常后循环继续
class Program {
static void Main(string[] args) {
Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; double[] arr = new double[]{
2.0, 7.94, 1.414 }; foreach(var item in arr) {
try {
operations(item); }catch(Exception e) {
Console.WriteLine(e.Message); } } Console.WriteLine($"Hello World"); } } class MathOpertions {
public static void MuliplyByTwo(double value) {
double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) {
double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } }
虽然循环继续,但是每次只执行第一个方法,因为第一个方法抛出异常后委托的迭代会停止。解决这个问题,需要自己迭代方法列表:
class Program {
static void Main(string[] args) {
Action<double> operations = null; operations = MathOpertions.MuliplyByTwo; operations += MathOpertions.Square; Delegate[] delegates = operations.GetInvocationList(); double[] arr = new double[]{
2.0, 7.94, 1.414 }; foreach(var item in arr) {
foreach(Action<double> d in delegates) {
try {
d(item); } catch (Exception e) {
Console.WriteLine(e.Message); } } } Console.WriteLine($"Hello World"); } } class MathOpertions {
public static void MuliplyByTwo(double value) {
double result = value * 2; Console.WriteLine($"MuliplyByTwo value={value} reult={result}"); throw new Exception("this is a Exception"); } public static void Square(double value) {
double result = value * 2; Console.WriteLine($"Square value={value} reult={result}"); } }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232867.html原文链接:https://javaforall.net