Action<T> 委托其实与[button url="http://redcat7.net/?p=343" style="dark"]Func<T, TResult> 委托[/button]一样,都是为了简化委托的使用,这两者的不同之处在于Action<T> 封装一个方法且该方法只有一个参数并且不返回值,而Func<T, TResult>封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。
使用 Action<T> 委托以参数形式传递方法,不用显式声明自定义的委托。 封装的方法必须与此委托定义的方法签名相对应。 也就是说,封装的方法必须具有一个通过值传递给它的参数,并且不能返回值。 (在 C# 中,该方法必须返回 void。 在 Visual Basic 中,必须通过 Sub…End Sub 结构来定义它。 它也可以是返回已忽略的值的方法。) 通常,这种方法用于执行某个操作。
那么Action<T>是如何简化委托调用的呢?
请先看委托传统的使用方法:
using System; using System.Windows.Forms; delegate void DisplayMessage(string message); public class TestCustomDelegate { public static void Main() { DisplayMessage messageTarget; if (Environment.GetCommandLineArgs().Length > 1) messageTarget = ShowWindowsMessage; else messageTarget = Console.WriteLine; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
上面的代码显式声明了一个名为 DisplayMessage 的委托,并将对 WriteLine 方法或 ShowWindowsMessage 方法的引用分配给其委托实例。
以下示例简化了此代码,它所用的方法是实例化 Action<T> 委托,而不是显式定义一个新委托并将命名方法分配给该委托。
using System; using System.Windows.Forms; public class TestAction1 { public static void Main() { Action<string> messageTarget; if (Environment.GetCommandLineArgs().Length > 1) messageTarget = ShowWindowsMessage; else messageTarget = Console.WriteLine; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
由此我们可以看出,通过使用Action<T> ,我们完美避开了对委托的定义,但缺点是它只接受一个参数,好在这个参数可以是任意类型,如果我们有多个参数需要传递,而又不想定义委托,那么我们可以新建一个对象类来封装我们的参数,以满足Action<T>对参数的要求。
Action<T>除了以上用法之外,还可以通过下面两种方法来达到相同的目的,但是没有上面的方法简单。
1. 我们也可以按照以下示例所演示的那样在 C# 中将 Action<T> 委托与匿名方法一起使用。
using System; using System.Windows.Forms; public class TestAnonMethod { public static void Main() { Action<string> messageTarget; if (Environment.GetCommandLineArgs().Length > 1) messageTarget = delegate(string s) { ShowWindowsMessage(s); }; else messageTarget = delegate(string s) { Console.WriteLine(s); }; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
2. 我们还可以按照以下示例所演示的那样将 lambda 表达式分配给 Action<T> 委托实例。
using System; using System.Windows.Forms; public class TestLambdaExpression { public static void Main() { Action<string> messageTarget; if (Environment.GetCommandLineArgs().Length > 1) messageTarget = s => ShowWindowsMessage(s); else messageTarget = s => Console.WriteLine(s); messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
完。