探讨c#中的泛型、委托、泛型委托、Action和Func及使用场景系列之二:委托

c#中委托定义了方法的类型,使得可以将方法当作参数来进行传递。使用委托的好处是:

1 . 避免在程序中大量使用If-Else(Switch)语句;

2 . 程序具有更好的可扩展性;

先看这样一个场景:如何根据客户端的要求将数据用不同的格式表示。

比如支付接口中支付成功后的提示信息,有的要用XML格式来返回给调用者,有的用JSON格式来返回,

我们先看不使用委托的编码方式 :

 

 1 public class Class5
 2     {
 3         public string NotifyPay(string code, string msg, string msgFormat)
 4         {
 5             if (msgFormat == "XML")
 6             {
 7                 return "<payInfo>"+
 8                             "<stateCode>"+ code + "</stateCode>"+
 9                             "<message>"+ msg + "</message>"+
10                         "</payInfo>";
11             }
12             else if (msgFormat == "JSON")
13             {
14                 return "{‘code‘:" + code + ",‘msg‘:‘" + msg + "‘}";
15             }
16             else
17             {
18                 return null;
19             }
20         }
21     }

在NotifyPay()方法中使用 if else语句来处理。

客户端调用方法如下:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             Class5 c5 = new Class5();
 7             string str5 = c5.NotifyPay("100", "SUCCESS", "XML");
 8             Console.WriteLine(str5);
 9 
10             Console.ReadLine();
11         }
12     }        

如果新加一个ini的格式(code=100  msg=SUCCESS)的客户端调用,则需要改写Class5中的NotifyPay( )方法,

这样每增加一个客户端格式就要加一个else if 语句,代码会越来越臃肿,而且实际项目中的逻辑更加复杂,

一旦某个语句出错,会使得所有客户端调用都无法工作,

是时候展现真正的技术了,现在我们用委托来实现这个需求:

 1     public delegate string NotifyDelegate(string code, string msg); //定义 NotifyDelegate 类型的委托
 2 
 3     public class Class6
 4     {
 5         public static string NotifyXml(string code, string msg)
 6         {
 7             return "<payInfo>"+
 8                      "<stateCode>"+ code + "</stateCode>"+
 9                      "<message>"+ msg + "</message>"+
10                    "</payInfo>";
11         }
12          
13         public static string NotifyJson(string code, string msg)
14         {
15             return "{‘code‘:"+ code + ",‘msg‘:‘"+ msg + "‘}";
16         }
17 
18         public static string NotifyIni(string code, string msg)
19         {
20             return "[payInfo]"+
21                      "code="+ code+
22                      "msg="+ msg;
23         }
24 
25 
26         public static string Notify(string code, string msg, NotifyDelegate nd) {
27 //这里可以加一些对code和msg的处理逻辑
28 if (code==null || msg==null) return null;
29 return nd(code, msg); 30 } 31 32 }

在第1行用delegate关键字声明了一个NotifyDelegate 类型的委托,它接受2个字符型的形参,返回一个字符串,

如果把delegate关键字去掉,实际上就是一个方法的声明,只要符合这样一个方法定义,都可以使用这个委托。

客户端调用如下:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         { 
 5             NotifyDelegate json; //声明一个NotifyDelegate类型的委托变量json
 6             
 7             json = new NotifyDelegate(Class6.NotifyJson);//用构造函数将Class6.NotifyJson这个方法赋值给委托变量 json
 8             
 9             //json = Class6.NotifyJson;  //也可直接将方法名赋值给委托变量 json ,实例方法需要先构造类的实例后在引用方法名(不需要带形参)
10
11 //将赋值后的委托变量 json 作为实参传入 12 string str6 = Class6.Notify("100", "SUCCESS", json); 13 Console.WriteLine(str6); //输出json格式 14 15 Console.ReadLine(); 16 } 17 }

首先声明一个NotifyDelegate类型的委托变量,然后用指定的方法赋值给这个委托变量。

(注 :指定的方法签名必须和这个委托完全相同,即形参和返回值要一样,

而不用管这个指定的方法是类方法还是实例方法,只要签名相同即可。)

赋值的方式有2种,用第7行或第9行的方式都可以,在第12行我们把赋值过的委托变量传入Notify( )方法中,

nd(code, msg)等同于调用NotifyJson(code, msg),所以输出了json格式的字符串。

如果要输出其他格式的字符串,只要将相关的方法赋值给json这个委托变量就可以了。

 

显而易见,用委托的形式编码之后后续项目中如果要增加其他格式的字符串输出,只要加入对应的方法就可以了,

原有的方法不需要改动一丝一毫,客户端要用哪种格式,则完全可以*去选择了。

 

探讨c#中的泛型、委托、泛型委托、Action和Func及使用场景系列之二:委托

上一篇:Win7系统运行PyCharm报错:无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-|1-1-0.dll


下一篇:C#9.0新特性详解系列之六:增强的模式匹配