程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【讀書筆記】C#高級編程 第十一章 LINQ,

【讀書筆記】C#高級編程 第十一章 LINQ,

編輯:C#入門知識

【讀書筆記】C#高級編程 第十一章 LINQ,


(一)LINQ概述

語言集成查詢(Language Integrated Query,LINQ)在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 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved