• 委托小结及Func用法


          首先,委托是一种类型,由关键字delegate声明。确切的说,委托是一种可用于封装命名或者匿名方法的引用类型。  它类似于 C++ 中的函数指针,而且是类型安全和可靠的。

          委托类型的声明与方法签名相似,有一个返回值和任意数目任意类型的参数。必须使用具有兼容返回类型和输入参数的方法或 lambda 表达式实例化委托。下面给出了委托声明及实例化的示例代码:

     1 // 委托声明 -- 定义一个签名:
     2 delegate double MathAction(double num);
     3 
     4 class DelegateTest
     5 {
     6     // 符合委托声明的常规方法
     7     static double Double(double input)
     8     {
     9         return input * 2;
    10     }
    11 
    12     static void Main()
    13     {
    14         // 使用一个命名方法实例化委托类型
    15         MathAction ma = Double;
    16 
    17         // 调用委托实例
    18         double multByTwo = ma(4.5);
    19         Console.WriteLine(multByTwo);
    20 
    21         // 再用匿名方法来实例化委托类型
    22         MathAction ma2 = delegate(double input)
    23         {
    24             return input * input;
    25         };
    26 
    27         double square = ma2(5);
    28         Console.WriteLine(square);
    29 
    30         // 最后用Lambda表达式来实例化委托类型
    31         MathAction ma3 = s => s * s * s;
    32         double cube = ma3(4.375);
    33 
    34         Console.WriteLine(cube);
    35     }
    36 }

    以上给出了一般情况下委托的使用,那么接下来我想继续了解Func<T, TResult>与委托的关系,还是直接从示例代码入手,请往下看代码:

     1 using System;
     2 
     3 delegate string ConvertMethod(string inString);
     4 
     5 public class DelegateExample
     6 {
     7    public static void Main()
     8    {
     9       // 用命名方法来实例化委托类型
    10       ConvertMethod convertMeth = UppercaseString;
    11       string name = "Dakota";
    12       // 通过实例化后的委托实例去调用该方法
    13       Console.WriteLine(convertMeth(name));
    14    }
    15 
    16    private static string UppercaseString(string inputString)
    17    {
    18       return inputString.ToUpper();
    19    }
    20 }

    在使用 Func<T, TResult> 委托时,不必显式定义一个封装只有一个参数的方法的委托。以下示例简化了此代码,它所用的方法是实例化 Func<T, TResult> 委托,而不是显式定义一个新委托并将命名方法分配给该委托。

     1 using System;
     2 
     3 public class GenericFunc
     4 {
     5    public static void Main()
     6    {
     7       // 依旧是用命名方法实例化委托类型
     8       Func<string, string> convertMethod = UppercaseString;
     9       string name = "Dakota";
    10       // 依旧是通过委托实例调用该方法
    11       Console.WriteLine(convertMethod(name));
    12    }
    13 
    14    private static string UppercaseString(string inputString)
    15    {
    16       return inputString.ToUpper();
    17    }
    18 }

    您也可以按照以下示例所演示的那样在 C# 中将 Func<T, TResult> 委托与匿名方法一起使用。

     1 using System;
     2 
     3 public class Anonymous
     4 {
     5    public static void Main()
     6    {
     7       Func<string, string> convert = delegate(string s)
     8          { return s.ToUpper();}; 
     9 
    10       string name = "Dakota";
    11       Console.WriteLine(convert(name));   
    12    }
    13 }

    您还可以按照以下示例所演示的那样将 lambda 表达式分配给 Func<T, TResult> 委托。

     1 using System;
     2 
     3 public class LambdaExpression
     4 {
     5    public static void Main()
     6    {
     7       Func<string, string> convert = s => s.ToUpper();
     8 
     9       string name = "Dakota";
    10       Console.WriteLine(convert(name));   
    11    }
    12 }

    Lambda 表达式的基础类型是泛型 Func 委托之一。  这样能以参数形式传递 lambda 表达式,而不用显式将其分配给委托。  尤其是,因为 System.Linq 命名空间中许多类型方法具有 Func<T, TResult> 参数,因此可以给这些方法传递 lambda 表达式,而不用显式实例化 Func<T, TResult> 委托。

    如果前面的解析看的不是很清楚,相信最后这个实例能够让你更加明白Func委托是多么有意思。

    下面的示例演示如何声明和使用 Func<T, TResult> 委托。  此示例声明一个 Func<T, TResult> 变量,并为其分配了一个将字符串中的字符转换为大写的 lambda 表达式。  随后将封装此方法的委托传递给 Enumerable.Select 方法,以将字符串数组中的字符串更改为大写。

     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 
     6 static class Func
     7 {
     8    static void Main(string[] args)
     9    {
    10       // 声明了一个Func委托类型的变量selector并用Lambda表达式进行实例化 
    11       // 这个Lambda表达式将用来获取一个字符串并将这个字符串转化为大写并返回
    12       Func<string, string> selector = str => str.ToUpper();
    13 
    14       // 创建一个字符串数组
    15       string[] words = { "orange", "apple", "Article", "elephant" };
    16       // 依次遍历这个字符串数组并调用委托实例selector进行处理
    17       IEnumerable<String> aWords = words.Select(selector);
    18 
    19       // 输出结果到控制台
    20       foreach (String word in aWords)
    21          Console.WriteLine(word);
    22    }
    23 }      
    24 /*
    25 This code example produces the following output:
    26 
    27    ORANGE
    28    APPLE
    29    ARTICLE
    30    ELEPHANT
    31 */

    通过委托和Lambda表达式及Func<>特性的结合,可以看出他们带给代码多么大的改变,不仅让我们的代码更加简洁,更让我们的代码执行起来更加高效灵活。个人希望通过对委托的一些整理,加深对委托的理解和运用!

  • 相关阅读:
    Tomcat下使用war包发布项目
    shell编程报错:“syntax error near unexpected token `”
    undo表空间不足,ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'
    HTML快速入门
    HTTP协议快速入门
    Java Web应用的开发模式
    使用Jekyll搭建免费的Github Pages个人博客
    前端模拟API数据的两种方式
    Node.js学习笔记
    socket.io笔记
  • 原文地址:https://www.cnblogs.com/newbies/p/delegate.html
Copyright © 2020-2023  润新知