2012-06-01 125 views
10

,我真搞明白它的內部工作 這是LINQ語法瞭解LINQ語法

string[] test = new test[] { "abc", "", "cd", "", "aa" }; 
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray(); 

我感到困惑的地方語法如何管理。它把所有的數組放在x中嗎?如果是,那麼它如何管理x空值?

如果不是那麼測試數組值一個一個放在x?

+0

http://msdn.microsoft.com/en-us /library/bb397687.aspx – archil

+0

看看這些文章:** http://msdn.microsoft.com/en-us/magazine/cc163400.aspx**和** http://daniel.wertheim.se/ 2011/02/07/c-clean-up-your-linq-queries-and-lambda-expressions/** –

+0

x包含數組中的一個單獨值,請查看我的回覆以獲取更多詳細信息 – Jupaol

回答

10

你應該考慮其餘的答案,它們相當準確,我想告訴你什麼,也許這將幫助你理解語法是這種查詢實際上可以用這樣的查詢語法表示:

string[] test=new test[]{"abc","","cd","","aa"}; 

// this is the equivalent to your code 
// added explicit type to make it clearer, it's optional 
var a = from (string)x in test 
     where !string.IsNullOrEmpty(x) 
     select x; 

,如果你熟悉SQL,你會發現這個語法更容易閱讀,即使你不知道吧,這句法更乾淨。

當代碼被編譯,這查詢語法自動轉換到C#方法的語法,以產生IL,所以如果你dissasmbly一個DLL,你會看到該方法的語法,而不是查詢語法

這段代碼的簡要說明:

  • 正如你可以看到一個x變量宣佈,它的string類型。爲什麼?因爲你的陣列是字符串數組

  • in test的指示源IEnumerable<>迭代 - 在這種情況下,你的陣列

  • where是相當自明,它只是從你的陣列選擇所有不爲空字符串

  • 最後,這些選擇實際上是數據的投影。

而這一切就相當於你的代碼

現在你可能會問自己......當我應該使用一個語法或其他?那麼它們是等價的,但查詢語法操作符是有限的,這意味着大多數操作都是使用方法語法而不是查詢語法來完成的。我總是做的是試圖編寫代碼更容易閱讀一些代碼更容易理解,如果它是用查詢語法編寫的。

關於方法語法,x => ...語法被稱爲lambda表達式,如果這是您第一次使用它們,但它們可能看起來很奇怪,但您最終會喜歡它們。

基本上lambda表達式是快捷方式的代表,所以你有做什麼:

x => !string.IsNullOrEmpty(x) 

你正在創建一個匿名方法,並且該方法被分配給委託的參數。 x代表string variable

這個主題非常廣泛,試圖在這裏解釋它,但我希望這給了你一個背後的想法。

順便說一句,你可以結合語法是這樣的:

// this is the equivalent to your code 
// added explicit type to make it clearer, it's optional 
var a = (from (string)x in test 
     where !string.IsNullOrEmpty(x) 
     select x).ToArray(); 

如果谷歌LINQ是像谷歌搜索PORM笑網存在着嚴重的LINQ物品,樣品等

好點開始將是101個樣本來自微軟

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

編輯

我會盡量模仿Where方法,所以你可以有lambda表達式

// this is basically the declaration of one overload of the Where method 
// the this in the parameter declaration, indicates this is an extension method which will be available to all IEnumerable<> objects 
// the Func<T, bool> is the interesting part, it is basically a delegate (as a reminder, the last parameter of the Func object indicates the type that must be returned, in this case is a bool) 
// the delegate is simply a pointer to a function 
public IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) 
{ 

    ...some logic 




    ... yielding back the reuslts 
    foreach(var r in res) 
    { 
     // here is the delegate in action 
     if(predicate(r)) 
      yield return r; 
    } 
} 

的一個更好的例子正如你所看到的委託被稱爲函數(代表是指向函數) 對接什麼功能?你在你的代碼

  • x => !string.IsNullOrEmpty(x)x聲明的一個指示從何處方法傳遞迴外部代碼,在那裏你可以檢查它並使用它來過濾搜索結果的參數

  • X =>是縮寫聲明一個代表

  • !string.IsNullOrEmpty(x)的這是您的匿名米體方法,你可以看到它滿足Func<T, bool>的要求,它返回一個bool(謂詞來過濾數組的元素),並且作爲一個參數,它接收到通用的T,在這種情況下,它是從你的數組中的字符串

另一種方式來聲明lambda表達式是:

test = test.Where(
      (string) x => 
      { 
       return !string.IsNullOrEmpty(x) 
      }) 
      .ToArray(); 

有了這個語法是很容易證明他們其實

2

編輯

閱讀這篇文章,你一定會得到很好的想法有關您writtnen ......

C# 3.0 New Language Features (Part 1)

C# 3.0 New Language Features (Part 2)


它是extenstion method + lambda experssion部分C#3.0

此處在此代碼

test=test.Where(x => !string.IsNullOrEmpty(x)).ToArray(); 

where - 是一個extesion方法

x => !string.IsNullOrEmpty(x) - 是λ-expresion,這是替換匿名函數

這整個功能檢查數組的每個元素...即lamdaba表達式檢查數組中的每個元素滿足寫入的條件並最終回退那些滿足條件的元素的數組

6

我們可以採取statem方法(匿名方法) ENT隔開並檢查件每次一個

x => !string.IsNullOrEmpty(x)基本上限定下面

bool Filter(string x){ 
    return !string.IsNullOrEmpty(x) 
} 

像的功能並基於該功能的謂詞。謂詞僅僅是一個委託 - 你可以傳入一個變量的函數。

.Where是,爲了簡化可以定義

IEnumerable<T> Where<T>(this IEnumerable<T> sequence,Predicate<T> pred){ 
    foreach(var elem in sequence){ 
     if(pred(elem)){ 
      yield return elem; 
     } 
    } 
} 

有你定義的功能Filter定義上面,而不是使用一個lambda你的說法是這樣的

test = test.Where(Filter).ToArray(); 

的擴展方法所以通過在你的數組上調用這個擴展方法並傳遞上面的謂詞,你將遍歷數組中的所有元素並返回所有匹配謂詞的元素(即,那些相互關聯的元素[R空也沒有空字符串的值)

最後調用擴展方法.ToArray()果然.Where返回了什麼(一IEnumerable<string>)到一個數組