C# 笔记 Func<TResult> 委托、Action<T> 委托

https://blog.csdn.net/wanglui1990/article/details/79303894

Func<ΤResult> 委托:代理(delegate)一个返回类型为「由参数指定的类型的值(TResul)」 的无参方法。使用 Func<ΤResult> 委托,无需显式定义一个委托与方法的关联。 
Func<ΤResult>原型:

public delegate TResult Func<out TResult>()
  • 1

Func<ΤResult>示例: 
主方法

namespace 异步操作
{
    class Program
    {
        static void Main(string[] args) { FuncDelegate fDel = new FuncDelegate(); fDel.ExplicitlyDeclaresTest(); fDel.SimplifiesByFuncT(); fDel.SimplifiesByFuncTAndAnonymousMethod(); fDel.SimplifiesByFuncTAndLambda(); fDel.ExtendFuncT(); ActionTtest aDel = new ActionTtest(); aDel.ExplicitlyDeclaresActionTTest(); aDel.SimplifiesByActionT(); aDel.SimplifiesByActionTAndAnonymousMethod(); aDel.SimplifiesByActionTAndLambda(); aDel.ExtendActionT(); Console.Read(); } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

示例代码:

namespace 异步操作
{
    //Func<TResult>() 委托:返回类型为TResult的无参方法。
    //Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> 委托:返回TResult类型,带9个参数的方法。
    //当您使用 Func<TResult> 委托时,您无需显式定义一个委托,用于封装无参数的方法。 例如,下面的代码显式声明的委托名为 WriteMethod 和分配的引用 OutputTarget.SendToFile 实例到其委托实例的方法。
    //https://msdn.microsoft.com/zh-cn/library/bb534960(v=vs.110).aspx

    public class OutputTarget { public bool SendToFile() { try { string fn = Path.GetTempFileName(); StreamWriter sw = new StreamWriter(fn); sw.WriteLine("Hello, World!"); sw.Close(); return true; } catch { return false; } } } delegate bool WriteMethod(); class FuncDelegate { //显式声明委托与方法的关联 public void ExplicitlyDeclaresTest() { OutputTarget output = new OutputTarget(); WriteMethod methodCall = output.SendToFile;//建立委托与方法的关联。 if (methodCall())//执行此行时,跳转去执行绑定的方法SendToFile() Console.WriteLine("Success!"); else Console.WriteLine("File write operation failed."); } //使用Func<TResult>简化 委托与方法的关联 public void SimplifiesByFuncT() { OutputTarget output = new OutputTarget(); Func<bool> methodCall = output.SendToFile;//简化关联 if (methodCall())//执行此行时,跳转去执行绑定的方法SendToFile() Console.WriteLine("Success!"); else Console.WriteLine("File write operation failed."); } //使用Func<TResult>和匿名方法简化 委托与方法的关联 public void SimplifiesByFuncTAndAnonymousMethod() { OutputTarget output = new OutputTarget(); Func<bool> methodCall = delegate () { return output.SendToFile(); };//匿名方法简化Func<T>与方法的关联 if (methodCall())//执行此行时,跳转去执行 绑定的匿名方法() { return output.SendToFile(); },执行完后返回 Console.WriteLine("Success!"); else Console.WriteLine("File write operation failed."); } //使用Func<TResult>和Lambda、匿名方法简化 委托与方法的关联 public void SimplifiesByFuncTAndLambda() { OutputTarget output = new OutputTarget(); Func<bool> methodCall = () => output.SendToFile();//Lambda、匿名方法 简化Func<T>与方法的关联 if (methodCall()) // 执行此行时,跳转去执行 绑定的() => output.SendToFile(),执行完后返回 Console.WriteLine("Success!"); else Console.WriteLine("File write operation failed."); } //扩展:以Funct<T>未参数类型传递。 public void ExtendFuncT() { //():匿名无参方法。() =>方法名,指派匿名无参方法去执行另外一个方法。 LazyValue<int> lazyOne = new LazyValue<int>(() => ExpensiveOne());//匿名无参方法被指派去执行ExpensiveOne LazyValue<long> lazyTwo = new LazyValue<long>(() => ExpensiveTwo("apple"));//匿名无参方法被指派去执行ExpensiveTwo Console.WriteLine("LazyValue objects have been created."); //泛型类别根据 关联的委托与方法 取值。 Console.WriteLine(lazyOne.Value);//跳转到() => ExpensiveOne(),执行LazyValue<T>.Value的取值,然后显示结果。 Console.WriteLine(lazyTwo.Value);//跳转到() => ExpensiveTwo("apple"),执行LazyValue<T>.Value的取值,然后显示结果。 } //无参测试方法 static int ExpensiveOne() { Console.WriteLine("\nExpensiveOne() is executing."); return 1; } //计算字串长度 static long ExpensiveTwo(string input) { Console.WriteLine("\nExpensiveTwo() is executing."); return (long)input.Length; } } //扩展:自定义泛型类别LazyValue T,以Funct<T>为参数类型传递。 class LazyValue<T> where T : struct { private T? val;//或 Nullable<T> val; //标记返回类型T,同时用于保存Func<T>委托的方法的返回值 private Func<T> getValue; //返回类型为T的委托 // 构造。参数Funct<T>类型:传入的参数为返回类型为TResult(任何类型)的无参方法。 public LazyValue(Func<T> func) { val = null; getValue = func; } public T Value { get { if (val == null) val = getValue();//取得委托方法的返回值。 return (T)val; //强制抓换委托方法返回值类型。 } } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

Action<Τ> 委托:代理(delegate)无返回值 参数类型为 T 的无参方法。使用 Action<Τ> 委托,无需显式定义一个委托与方法的关联。 
Action<Τ>原型:

public delegate void Action<in T>(
    T obj
)
  • 1
  • 2
  • 3

Action<Τ>示例代码:

namespace 异步操作
{

    delegate void DisplayMessage(string message);//委托:一个string类型参数、无返回值的方法
    public class ActionTOutputTarget { public void ShowWindowsMessage(string message) { Console.WriteLine(message); } } class ActionTtest { //显式声明委托与方法的关联 public void ExplicitlyDeclaresActionTTest() { DisplayMessage methodCall;//委托名methodCall ActionTOutputTarget output = new ActionTOutputTarget(); if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入 methodCall = output.ShowWindowsMessage; else methodCall = Console.WriteLine; methodCall("Hello, World!"); //执行带参方法。 } //使用Action<T>简化 委托与方法的关联 public void SimplifiesByActionT() { ActionTOutputTarget output = new ActionTOutputTarget(); Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法 if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入 methodCall = output.ShowWindowsMessage; else methodCall = Console.WriteLine; methodCall("Hello, World!"); //执行带参方法。 } //使用Action<T>和匿名方法简化 委托与方法的关联 public void SimplifiesByActionTAndAnonymousMethod() { ActionTOutputTarget output = new ActionTOutputTarget(); Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法 if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入 methodCall = delegate (string s) { output.ShowWindowsMessage(s); };//匿名方法参数签名(string s) else methodCall = delegate (string s) { Console.WriteLine(s); }; methodCall("Hello, World!"); //执行带参方法。 } //使用Action<T>和Lambda、匿名方法简化 委托与方法的关联 public void SimplifiesByActionTAndLambda() { ActionTOutputTarget output = new ActionTOutputTarget(); Action<string> methodCall = output.ShowWindowsMessage;//简化关联。关联带一个string类型参数的方法 if (Environment.GetCommandLineArgs().Length > 1)//接收命令行输入 methodCall = (string s)=> { output.ShowWindowsMessage(s); };//Lambda参数s传递给匿名方法,方法体{ output.ShowWindowsMessage(s); } else methodCall = (string s)=> { Console.WriteLine(s); }; methodCall("Hello, World!"); //执行带参方法。 } //扩展:以Action<T>为参数类型传递。 public void ExtendActionT() { List<String> names = new List<String>(); names.Add("Bruce"); names.Add("Alfred"); names.Add("Tim"); names.Add("Richard"); Console.WriteLine("==========List<string>.ForEach(Action<T> action>======="); //以Action<T>类型为参数 List<string> ForEach:public void ForEach(Action<T> action); names.ForEach(Print); Console.WriteLine("==========匿名方法 delegate(string name)={Console.WriteLine();}======="); // 匿名方法 names.ForEach(delegate (string name) { Console.WriteLine("console:"+name); }); } private void Print(string s) { Console.WriteLine("Print:"+s); } } }

总结:以后如果要新建委托与方法关联,可简化代码如下(使用匿名方法+Lambda+Func<Τ>)。

//Func<bool> methodCall = () => output.SendToFile()
//methodCall()//执行 关联的方法() Func<关联方法返回类型> methodCall = () => 关联的方法()//传递匿名无参方法() 并与想要执行方法关联(=>),可关联方法可任意参数,但必须有返回类型(无返回值的用Action<T>)。 methodCall()。//执行 关联的方法

猜你喜欢

转载自www.cnblogs.com/liuqiyun/p/9198116.html