• 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();
            }
        }
    }

    示例代码:

    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("
    ExpensiveOne() is executing.");
                return 1;
            }
            //计算字串长度
            static long ExpensiveTwo(string input)
            {
                Console.WriteLine("
    ExpensiveTwo() 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;      //强制抓换委托方法返回值类型。
                }
            }
        }
        }

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

    public delegate void Action<in T>(
        T obj
    )

    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()。//执行 关联的方法
  • 相关阅读:
    spark streaming 概述
    spark sql 的性能调优
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)
    LeetCode 90. Subsets II (子集合之二)
    LeetCode 88. Merge Sorted Array(合并有序数组)
    LeetCode 81. Search in Rotated Sorted Array II(在旋转有序序列中搜索之二)
    LeetCode 80. Remove Duplicates from Sorted Array II (从有序序列里移除重复项之二)
    LeetCode 79. Word Search(单词搜索)
    LeetCode 78. Subsets(子集合)
  • 原文地址:https://www.cnblogs.com/liuqiyun/p/9198116.html
Copyright © 2020-2023  润新知