zoukankan      html  css  js  c++  java
  • 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()。//执行 关联的方法
  • 相关阅读:
    p1373【奶牛的卧室】
    p1248【交错匹配】(DP)
    QBXT模拟赛T3
    NOIP冲刺班的考试总结
    欧拉回路的一些东西
    一道dp题目
    Blocks
    玩具取名
    Y的积木
    游荡的奶牛
  • 原文地址:https://www.cnblogs.com/liuqiyun/p/9198116.html
Copyright © 2011-2022 走看看