封装包含两个参数的方法委托,没有返回值。
public delegate void Action<in T1, in T2>( T1 arg1, T2 arg2 )
in T1:委托封装方法的第一个参数类型,此类型参数逆变。
可以使用Action<T1, T2>委托以参数形式传递方法,而不用自定义委托。封装的方法必须与此委托的方法签名一致。也就是说,封装的方法也要有两个参数,没有返回值。
下面显式声明了一个名为ConcatStrings的委托。然后,它将两个方法中的任意一个的引用分配给其委托实例。其中一个方法将两个字符串写入控制台;另一个将两个字符串写入文件。
using System; using System.IO; delegate void ConcatStrings(string string1, string string2); public class TestDelegate { public static void Main() { string message1 = "The first line of a message."; string message2 = "The second line of a message."; ConcatStrings concat; if (Environment.GetCommandLineArgs().Length > 1) concat = WriteToFile; else concat = WriteToConsole; concat(message1, message2); } private static void WriteToConsole(string string1, string string2) { Console.WriteLine("{0}\n{1}", string1, string2); } private static void WriteToFile(string string1, string string2) { StreamWriter writer = null; try { writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false); writer.WriteLine("{0}\n{1}", string1, string2); } catch { Console.WriteLine("File write operation failed..."); } finally { if (writer != null) writer.Close(); } } }
下面以Action<T1, T2>委托简化上面的代码:
using System; using System.IO; public class TestAction2 { public static void Main() { string message1 = "The first line of a message."; string message2 = "The second line of a message."; Action<string, string> concat; if (Environment.GetCommandLineArgs().Length > 1) concat = WriteToFile; else concat = WriteToConsole; concat(message1, message2); } private static void WriteToConsole(string string1, string string2) { Console.WriteLine("{0}\n{1}", string1, string2); } private static void WriteToFile(string string1, string string2) { StreamWriter writer = null; try { writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false); writer.WriteLine("{0}\n{1}", string1, string2); } catch { Console.WriteLine("File write operation failed..."); } finally { if (writer != null) writer.Close(); } } }
其实就是预先定义好的委托,不需要自定义对应参数的委托了。
还可以同匿名方法一起使用:
using System; using System.IO; public class TestAnonymousMethod { public static void Main() { string message1 = "The first line of a message."; string message2 = "The second line of a message."; Action<string, string> concat; if (Environment.GetCommandLineArgs().Length > 1) concat = delegate(string s1, string s2) { WriteToFile(s1, s2); }; else concat = delegate(string s1, string s2) { WriteToConsole(s1, s2);} ; concat(message1, message2); } private static void WriteToConsole(string string1, string string2) { Console.WriteLine("{0}\n{1}", string1, string2); } private static void WriteToFile(string string1, string string2) { StreamWriter writer = null; try { writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false); writer.WriteLine("{0}\n{1}", string1, string2); } catch { Console.WriteLine("File write operation failed..."); } finally { if (writer != null) writer.Close(); } } }
也可以将匿名函数替换为lambda表达式:
using System; using System.IO; public class TestLambdaExpression { public static void Main() { string message1 = "The first line of a message."; string message2 = "The second line of a message."; Action<string, string> concat; if (Environment.GetCommandLineArgs().Length > 1) concat = (s1, s2) => WriteToFile(s1, s2); else concat = (s1, s2) => WriteToConsole(s1, s2); concat(message1, message2); } private static void WriteToConsole(string string1, string string2) { Console.WriteLine("{0}\n{1}", string1, string2); } private static void WriteToFile(string string1, string string2) { StreamWriter writer = null; try { writer = new StreamWriter(Environment.GetCommandLineArgs()[1], false); writer.WriteLine("{0}\n{1}", string1, string2); } catch { Console.WriteLine("File write operation failed..."); } finally { if (writer != null) writer.Close(); } } }
后两者都没有起到简化代码的作用。