封裝包含兩個參數的方法委托,沒有返回值。
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(); } } }
後兩者都沒有起到簡化代碼的作用。