zoukankan      html  css  js  c++  java
  • 【读书笔记】C#高级编程 第十一章 LINQ

    (一)LINQ概述

    语言集成查询(Language Integrated QueryLINQ)在C#编程语言中继承了查询语法,可以用相同的语法访问不同的数据源。

    1、LINQ查询

    var query = from r in Formula1.GetChampions()
    
                where r.Country == "Brazil"
    
                orderby r.Wins descending
    
                select r;

    这是一个LINQ查询,子句from、where、orderby、descending和select都是这个查询中预定义的关键字。

    2、扩展方法

    扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义了它扩展的类型。

    例子:

    public static void WriteWithTime(this string message)
    {
        Console.WriteLine(message + "," + DateTime.Now.ToString("yyyy-MM-dd"));
    }

    为了和一般的静态方法进行区分,扩展方法还需要对第一个参数使用this关键字。

    现在可以使用带string类型的WriteWithTime()方法了。

    例子:

    string message = "test txt";
    
    message.WriteWithTime();

    定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable。

    例子:

    List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
    
    var maxIntList = intList.Where(i => i > 4);

    这里使用Where扩展方法获取大于4的值。

    3、推迟查询的执行

    在运行期间定义查询表达式时,查询就不会运行。查询会在迭代数据项时进行。

    例子:

    List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
    
    var maxIntList = intList.Where(i => i > 4);
    
    foreach (var item in maxIntList)
    
    {
    
        Console.WriteLine(item);
    
    }
    
    intList.Add(6);
    
    foreach (var item in maxIntList)
    
    {
    
        Console.WriteLine(item);
    
    }

    运行以上代码,结果如下:

     

    需要注意的是,每次在迭代中使用查询时,都会调用扩展方法(可以检测出数据源中的变化)。但调用扩展方法ToArray()ToList()可以改变这个操作。

    例子:

    List<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
    
    var maxIntList = intList.Where(i => i > 4).ToList();//调用ToList()方法
    
    foreach (var item in maxIntList)
    
    {
    
        Console.WriteLine(item);
    
    }
    
    intList.Add(6);
    
    foreach (var item in maxIntList)
    
    {
    
        Console.WriteLine(item);
    
    }

    运行以上代码,结果如下:

     

     

    (二)标准的查询操作符

    参考:http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html

    (三)并行LINQ

    1、并行查询

    例子:

    var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
    
    var res = data.AsParallel().Where(d => d > 2);

    调用AsParaller()方法进行LINQ并行查询。

    2、分区器

    AsParallel()方法不仅扩展了IEnumerable<T>接口,还扩展了System.Collection.Concurrent名称空间的Partitioner类。

    例子

    var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
    
    var result = Partitioner.Create(data, true).AsParallel().Where(d => d > 2);

    使用Create()方法手工创建一个分区器。

    3、取消

    .NET提供了一种标准方式,来取消长时间运行的任务,这也适用于并行LINQ。

    例子:

    var data = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 };
    var cts = new CancellationTokenSource();
    Task.Factory.StartNew(()=> {
        try
        {
            var resu = data.AsParallel().WithCancellation(cts.Token).Where(d => d > 2);
            Console.WriteLine("查询结束");
        }
        catch (OperationCanceledException ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
    });
    Console.WriteLine("查询开始");
    Console.WriteLine("取消?");
    string input = Console.ReadLine();
    if (input.ToLower().Equals("y"))
    {
        cts.Cancel();
    }

    给并行查询处添加WithCancellation()方法,参数为CancellationToken令牌为参数。当取消查询时会抛出OperationCanceledException类型的异常,捕捉异常后可以使用Cancel()方法取消查询任务。

    (四)表达式树

    C#编译器根据类型给lambda表达式定义不同的行为,当类型为Expression<T>,编译器就从lambda表达式中创建一个表达式树,并存储在程序集中。

    例子:

     1 static void Main(string[] args)
     2 {
     3     Expression<Func<int, bool>> expression = s => s > 1 ;
     4     DisplayTree(0, "lambda", expression);
     5     Console.ReadKey();
     6 }
     7 static void DisplayTree(int indent, string message, Expression expression)
     8 {
     9     string outPut = string.Format("{0} {1} ! NodeType: {2}; Expr: {3}", "".PadLeft(indent, '>'), message, expression.NodeType, expression);
    10     indent++;
    11     switch (expression.NodeType)
    12     {
    13         case ExpressionType.Constant:
    14             ConstantExpression constExpr = (ConstantExpression)expression;
    15             Console.WriteLine("{0} Const Value: {1}", outPut, constExpr.Value);
    16             break;
    17         case ExpressionType.Equal:
    18         case ExpressionType.AndAlso:
    19         case ExpressionType.GreaterThan:
    20             BinaryExpression binExpr = (BinaryExpression)expression;
    21             if (binExpr.Method != null)
    22             {
    23                 Console.WriteLine("{0} Method: {1}", outPut, binExpr.Method.Name);
    24             }
    25             else
    26             {
    27                 Console.WriteLine(outPut);
    28             }
    29             DisplayTree(indent, "Left", binExpr.Left);
    30             DisplayTree(indent, "Right", binExpr.Right);
    31             break;
    32         case ExpressionType.Lambda:
    33             Console.WriteLine(outPut);
    34             LambdaExpression lambdaExpr = (LambdaExpression)expression;
    35             foreach (var item in lambdaExpr.Parameters)
    36             {
    37                 DisplayTree(indent, "Parameter", item);
    38             }
    39             DisplayTree(indent, "Body", lambdaExpr.Body);
    40             break;
    41         case ExpressionType.MemberAccess:
    42             MemberExpression memberExpr = (MemberExpression)expression;
    43             Console.WriteLine("{0} Member Name: {1}, Type: {2}", outPut, memberExpr.Member.Name, memberExpr.Type.Name);
    44             DisplayTree(indent, "Member Expr", memberExpr.Expression);
    45             break;
    46         case ExpressionType.Parameter:
    47             ParameterExpression parameExpr = (ParameterExpression)expression;
    48             Console.WriteLine("{0} Param Type: {1}", outPut, parameExpr.Type.Name);
    49             break;
    50         default:
    51             Console.WriteLine();
    52             Console.WriteLine("{0} {1}", expression.NodeType, expression.Type.Name);
    53             break;
    54     }
    55 }
  • 相关阅读:
    EF-入门操作
    Razor 页面解说
    Razor_02 第一个应用程序+Model+EF 添加
    Razor_01 第一个应用程序
    LazyCoder修仙之路
    .NET高级特性-Emit(2.2)属性
    .NET高级特性-Emit(2.1)字段
    .NET高级特性-Emit(2)类的定义
    .NET高级特性-Emit(1)
    asp.net core高级应用:TagHelper+Form
  • 原文地址:https://www.cnblogs.com/dlxh/p/6686867.html
Copyright © 2011-2022 走看看