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


    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()。//执行 关联的方法
    ---------------------
    作者:tb_
    来源:CSDN
    原文:https://blog.csdn.net/wanglui1990/article/details/79303894
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    win8 连接到OneDrive时出现问题-感叹号
    让tp6显示详细的错误信息及行号
    TP6出现错误 No input file specified.
    Git 访问慢 解决办法
    mysql5.7当两个字段名类似,查询时会出错
    linux停止进程
    mysql更新数据时:当想mysql某插入有某字段设置了unique且和之前相同时,会报错,并停止运行
    php升级版本后的影响5.5->7.1


  • 原文地址:https://www.cnblogs.com/asdyzh/p/9870085.html
Copyright © 2020-2023  润新知