打赏

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("\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;      //强制抓换委托方法返回值类型。
            }
        }
    }
    }

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()。//执行 关联的方法
posted @ 2018-06-19 13:10  刘奇云  阅读(1733)  评论(0编辑  收藏  举报