Linq學習筆記(轉)

開始Linq前你要知道的

  擴展方法

  顧名思義就是對現有類進行擴展的的方法,擴展方法可以在不修改現有類的情況下,為現有類增加公共的接口(不是C#中的interface)。

  擴展方法本質上是一個靜態方法,不同之處在于它的第一個參數必須有this關鍵字聲明,并且第一個參數的類型即為要擴展的類型。如

public static double ToDouble(this string source)
{double res = 0d;double.TryParse(source, out res);return res;
}public static void SimpleExtesionMethod()
{double d = "12345.54321".ToDouble();Console.WriteLine(d);
}

這里是個簡單的將字符串轉為double類型的擴展方法,只要引用了該方法的命名空間,則都可以直接用string類型來調用ToDouble方法。

  擴展方法是后文的基礎,C#3.0中的Linq的實現都是基于擴展方法,通過對IEnumerable<T>接口(Linq to Objects)的擴展和對IQueryable<T>的擴展來實現Linq的相關功能,而Linq的相關關鍵字最終都是轉化為對IEnumerable<T>(IQueryable<T>)的調用。

  Lambda表達式

  lambda表達式其實就是.net2.0中的匿名方法,然后再3.0中以一種更優美的姿態呈現出來。

  lambda表達式的基本語法為

  (參數列表) =>{語句塊;}??? 或者  ( 參數列表) =>表達式

  當參數列表中只有一個參數的時候,圓括號可以省略

Func<string, string> func = x => x + x;
Console.WriteLine(func("a")); 

Var:隱式類型化變量

  使用與可以由編譯器推導出的變量的聲明,不需要顯式指定對象的類型。

var container = new List<string> { "張三", "李四", "王五" };
IEnumerable<string> query = from name in containerselect name;

?

上例中由于定義中已經指明了對象的類型,聲明中已經完全沒有必要使用顯示的類型定義,所以可以使用var關鍵字。

  對于匿名對象

var test = new { Name = "Sth.", Type = "UnKnown" };

由于無法用一個類型類聲明匿名對象,此時可以用var是聲明。

  注意var只是省下了顯式聲明的過程,而C#本身就是靜態語言,所以var所聲明的變量的類型已經確定任然是不能改變的,亦即,var并非是變體類型。

Linq對誰適用

  linq的語法通過System.Linq下面的Enumerable類提供支持,通過觀察他的簽名,你就會發現他為IEnumerable<T>實現了一系列的擴展方法,也就是說,只要是實現了IEnumerable<T>的對象都可以使用Linq的語法來查詢

  而對于只實現了IEnumerable接口而沒有實現IEnumerable<T>的對象可以通過

?

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source);

?

來將IEnumerable接口轉為IEnumerable<T>(例如ArrayList)。

Linq中的關鍵字

  在C#3.0中,為Linq引入了一些新的關鍵字,他們是:

  from join where group into let orderby select

  熟悉Sql的同學看著是不是有些眼熟呢,其實在Linq中他們的涵義和在SQL中類似的,所以會很容易理解的。接下來的時間,簡單介紹下這些關鍵字的使用。

from

  from子句是一個Linq查詢的開始,任何一個Linq語句都是以from開始,from子句指定查詢的容器,和在此語句有效的局部變量(用來指定容器中的一項,from子句的效果很類似于foreach)。from子句的語法為

 from local in container

local就是在此Linq語句中的局部變量,由于container必須為IEnumerable<T>,他的類型可以由container推導出來(即T)。上一段簡單的例子:

ar container = new List<string> { "張三", "李四", "王五" };
var query = from name in containerselect name;foreach (string name in query)
{Console.WriteLine(name);
}

輸出:

張三
李四
王五

如果container僅僅實現IEnumerable而沒有實現IEnumerable<T>,則需要顯式指定局部變量的類型,或者是使用Cast轉為IEnumerable<T>

var container = new ArrayList { "張三", "李四", "王五" };
var query = from name in container.Cast<string>()select name;
//或者
var query1 = from string name in containerselect name;

select

  對查詢的結果進行投影,在子句中指定要選擇的列,如上例。有的時候,我們只需要投影某一列,我們可以這樣

private static void TestSelectSingleProperty()
{var persons = GetPersons();var query = from p in personsselect p.Name;foreach (var item in query){Console.WriteLine(item);}
}

我們還可以指定要投影的列的集合,這個時候我們要用到匿名類型

var query = from p in personsselect new { p.ID, p.Name };foreach (var item in query)
{Console.WriteLine("No:{0},Name:{1}",item.ID,item.Name);
}

query中的每一項都時候一個擁有ID屬性和Name屬性的對象,當然有的時候實體的屬性名不是我們想要的,或者是通過對屬性計算得來的,那么我們可以顯式指定屬性名,就像下面這樣:

var query = from p in personsselect new{UserID = p.ID,FriendName = p.Gender == "" ? "Mr" : "Ms" + p.Name};foreach (var item in query)
{Console.WriteLine("No:{0},Friendly Name:{1}", item.UserID, item.FriendName);
}

where

  對容器內的數據進行篩選。

var query = from p in personswhere p.DepartmentID == 1select p.Name;

join

  類似SQL里的join,Linq中的join子句用于將兩個容器的數據以某種關系進行關聯。

var departments = GetDepartments();
var persons = GetPersons();var query = from d in departmentsjoin p in persons on d.ID equals p.DepartmentIDselect new { d, p };

值得注意的是join子句只能使用equals或者是not equal而不能用其他運算符(==都不行)而equals運算符左邊必須聯接的左部,右邊為右部,不能調換的,否則編譯不能通過。

into

  into子句用于將join或者是group子句的結果進一步持續化,包裝成為一個

  System.Linq.IGrouping<TKey, TElement>對象,

  而且IGrouping繼承自IEnumerable<TElement>,可以看出,IGrouping接口提供分組的鍵和,該鍵下所包含的集合。例子見group

group

  對結果按照指定的條件進行分組

var container = new List<string> { "ZhangSan", "LiSi", "Wangwu", "ZhaoLiu", "Deng" };
var query = from name in containergroup name by name.Length into gselect new { g.Key, Values = g };

例子演示了通過姓名的長度對一個姓名列表進行分組,并將分組的結果保持到局部變量g中,可以通過下面的代碼將query的結果輸出

foreach (var group in query)
{Console.WriteLine("{0}:", group.Key);foreach (var item in group.Values){Console.WriteLine(item);}
} 

let

  let子句用于在查詢中添加一個新的局部變量,使其在后面的查詢中可見

var query = from p in personslet friendlyName = p.Gender == "" ? "Mr" : "Ms" + p.Nameselect new{UserID = p.ID,FriendName = friendlyName};foreach (var item in query)
{Console.WriteLine("No:{0},Friendly Name:{1}", item.UserID, item.FriendName);
}

在IEnumerable<T>上的其他擴展

  Take Skip

  用于選取前XX個或者和跳過前XX個,如選擇第11到20個則可以

query.Skip(10).Take(10);

OrderBy OrderByDescending

  排序而已

query.OrderBy(c => c.Length);

Distinct Union Intersect Except 這些單詞都見過吧,分別就是取不重復,并集,交集,差集(這個貌似看看參數就明白了)

  其他擴展都在Enumerable類下面了。

  Linq的延遲加載特性

  Linq查詢的執行結果是IEnumerable<T>類型,而對IEnumerable<T>,在內部,C#通過yield關鍵字實現迭代器達到延遲加載的目的。從而使Linq查詢只是在需要的時候才會被執行。

  但是,某一些擴展方法在執行時會試圖遍歷整個容器,從而使延遲加載無效,如排序,聚合函數(Count,Sum,Average等。)

static IEnumerable<int> InfinityInts()
{int count = 0;while (true)yield return count++;
}public static void LazyLoad()
{var query = from i in InfinityInts()select i;foreach (var i in query.Take(20)){Console.WriteLine(i);}
}public static void CantDoLazyLoad()
{var query = from i in InfinityInts()select i;foreach (var i in query.OrderBy(i => i).Take(20)){Console.WriteLine(i);}
}

這里有個簡單的例子來證明,當使用Take時候,Linq語句能正常的執行,而當我們再Linq上使用一個Order By之后,程序就卡死了,當然,這是理所應當的,在失去延遲加載的特性之后,試圖對一個無窮序列排序的結果一定是outOfMemory。

?

轉載于:https://www.cnblogs.com/alsf/p/5993432.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372150.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372150.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372150.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cass展點不在原位置,cass中打開一副圖后,通過繪圖處理-——展高程點,怎么之前的圖形就不顯示了,,只剩下高程點!!...

答&#xff1a;1、進入控制面板&#xff0c;選擇“卸載或更改程序”。 2、選中“AutoCAD2006”圖標。 3、右擊選擇“更改”。 4、進入“AutoCAD2006安裝程序對話框”&#xff0c;選擇“添加/刪除功能”單選按鈕&#xff0c;點擊下一步。 5、在“程序文件”列表中&#xff0c;選…

(二)windows下安裝PHPCMS V9

一、準備工作 搭建環境 &#xff1a;參考:Windows下搭建PHP開發環境及相關注意事項PHPCMS V9 &#xff1a;下載適合自己 PHPCMS V9 版本到本地或服務器&#xff0c;下載地址&#xff1a;http://www.phpcms.cn/html/download/說明&#xff1a;官方提供了 2 種不同的編碼。包括 G…

JavaFX 2.0布局窗格– HBox和VBox

如果要對JavaFX 2.0中所有不同的布局窗格進行概述&#xff0c;或者想了解有關它們的一些基本知識&#xff0c;請參閱我以前的文章《 JavaFX 2.0中的布局窗格》 。 布局窗格HBox和VBox絕對是JavaFX 2.0中最基本的布局容器。 如您所知&#xff0c;它們的用途是將所有子級布置在一…

flask mysql分頁,Flask分頁的實現方法

所需環境Flask-SQLAlchemy分頁使用Flask-SQLAlchemy提供的pagination()方法。頁數是pagination()方法的第一個參數&#xff0c;也是唯一必須的參數。可選參數per_page用來指定每頁顯示的記錄數。參考代碼&#xff1a;def index():# ...page request.args.get(page, 1, typeint…

Java中的生成器設計模式

Java 中的 Builder設計模式是一種創建模式&#xff0c;即用于創建對象&#xff0c;類似于 工廠方法設計模式 &#xff0c;這也是創建設計模式。 在學習任何設計模式之前&#xff0c;我建議先找出特定設計模式要解決的問題。 眾所周知&#xff0c; 必要性是發明的母親。 在沒有面…

驗證碼( 隨機數)

方式一&#xff08;變色版&#xff09;&#xff1a; <html> <head><meta charset"UTF-8"/><title></title><script src"jquery-2.0.2.min.js"></script> </head> <body> <?php header("co…

單片機串行通信全解析

1.什么是串行通信&#xff1f; 串行通信&#xff08;英語&#xff1a;Serial communication&#xff09;是指在計算機總線或其他數據通道上&#xff0c;每次傳輸一個位元數據&#xff0c;并連續進行以上單次過程的通信方式。與之對應的是并行通信&#xff0c;它在串行端口上通過…

java type 類型,java中的泛型類型與Type接口

假設我們定義了一個Room的類&#xff0c;表示一個房間public classRoom(){}由于我們建造好房間是&#xff0c;不知道房間以后的用途&#xff0c;他可能用來住人&#xff0c;也有可能用來放貨物&#xff0c;因此需要用到泛型。但是我們可能想獲取Room這個房間里面進來的的東西的…

centos7下操作防火墻

引言 最近使用centos7系統比較頻繁&#xff0c;在配置服務器的時候&#xff0c;總是遇到能夠ping通服務器&#xff0c;但是就是沒有辦法訪問80端口&#xff0c;這個時候我的直覺告訴我&#xff0c;肯定是防火墻的原因&#xff0c;但是使用iptables卻怎么都找不到命令&#xff0…

其他團隊對本團隊評價的總結

我們小組在看了其他小組的評價后&#xff0c;對自己的程序有了新的看法。轉載于:https://www.cnblogs.com/bk1246788/p/6879691.html

Java:使用Fork / Join框架的Mergesort

此項的目的是顯示一個Fork / Join RecursiveAction的簡單示例&#xff0c;而不是過多地研究合并合并的可能優化方法&#xff0c;或者比使用Exkutor / Join Pool優于現有的基于Java 6的現有實現&#xff08;例如ExecutorService&#xff09;的相對優勢。 以下是使用Java的自上而…

php的異常處理方式,php異常處理基本方法

當一個php腳本運行時&#xff0c;為了防止腳本運行崩潰&#xff0c;亦或是當php作為webserver&#xff0c;為了防止php程序出錯&#xff0c;拋出httpcode500錯誤&#xff0c;我們常常需要對php程序做異常處理。今天介紹的是最基本的異常處理方法&#xff1a;一般而言&#xff0…

關系型數據庫的三范式

第一范式:確保每列的原子性. 如果每列(或者每個屬性)都是不可再分的最小數據單元(也稱為最小的原子單元),則滿足第一范式. 例如:顧客表(姓名、編號、地址、……)其中"地址"列還可以細分為國家、省、市、區等。第二范式:在第一范式的基礎上更進一層,目標是確保表…

vray學習筆記(3)-多維子材質是個什么東西

多維子材質是個什么東西&#xff1f;為什么出現這個概念&#xff1f; 在3dsmax官方網站&#xff0c;我們可以看到它的定義&#xff1a; The Multi/Sub-Object material lets you assign different materials at the sub-object level of your geometry. 意思是多維子材質這個概…

Hello JavaFX 2.0:命令行介紹

我從博客文章Hello JavaFX 2.0&#xff1a;NetBeans 7.1 beta的介紹中&#xff0c;從NetBeans 7.1 beta的角度看了一個無處不在的Hello World示例的簡單JavaFX版本。 在本文中&#xff0c;我將介紹僅使用命令行工具通過JavaFX實現的Hello World版本。 JavaFX 2.0 API文檔包括ja…

matlab空格會消失了,如何在Matlab中自動刪除保存的尾隨空格?

我有同樣的需求,并寫了一個小腳本來做一些接近的事情.將以下內容放在MATLAB desktop shortcut中.每當您單擊快捷方式按鈕時,它將從編輯器中的活動文件中刪除尾隨空格.不如在保存時自動執行它 – 你需要記住在保存之前按下按鈕 – 但差不多.測試在11b,12a和13b,但在12b也應該沒問…

object to 字符串json

1 package com.beijxing.TestMain;2 3 import com.beijxing.entity.Student;4 import com.google.gson.Gson;5 import com.google.gson.annotations.SerializedName;6 7 /** 8 * 9 * author 作者 : ywp 10 * version 創建時間&#xff1a;2016年10月30日 下午9:21:33 11 */ 12…

JS 對象(Object)和字符串(String)互轉

var jsObj {}; jsObj.testArray [1,2,3,4,5]; jsObj.name CSS3; jsObj.date 8 May, 2011; var str JSON.stringify(jsObj); var str1 JSON.parse(str); var str2 JSON.stringify(str1);alert(str);alert(str1); alert(str2);對象拷貝&#xff1a;var newObj JSON…

php 后退按鈕事件,php – 后退按鈕的會話問題

我在php文件中有這個代碼,它包含在我要共享的所有頁面中并保護我的頁面.session_name("login");session_start();if (!isset($_SESSION[UserId])) {if(!header("Location: https://subdomain.mywebsite.com/")){ die("Unauthorized access"); }}…

異常:java lang AbstractMethodError

通常在嘗試調用抽象方法時拋出此java.lang.AbstractMethodError。通常&#xff0c;此錯誤是在編譯時本身識別的&#xff0c;如果在運行時拋出此錯誤&#xff0c;則該類必須不兼容&#xff08;與先前存在的類不兼容&#xff09; &#xff09;更改。因此&#xff0c;它是Incompat…