簡體   English   中英

在c#中使用擴展方法與lambda表達式

[英]Using Extension methods versus lambda expression in c#

假設我有一個擴展方法

    public static IEnumerable<Product> Filter(
    this IEnumerable<Product> productEnum,
    Func<Product, bool> selectorParam)
    {
        return productEnum.Where(selectorParam);
    }

我稱之為

    Func<Product, bool> languageFilter = prod => prod.Language == lang;

如果我沒有被誤刪,在功能上是相同的

var products = Products.Where(q => q.Language == parameter);

我試圖理解何時可以使用第一個樣本的擴展方法,以及何時使用linq語法。

我認為你混淆了一些術語。 您顯示的Filter方法是一個擴展方法(由參數列表中的this關鍵字指示。您稱之為“linq語法”實際上是一個lambda表達式。

所有LINQ方法都實現為擴展方法,並支持兩種調用“樣式”:

  1. 實際上直接調用擴展方法就好像它們是被擴展類型的一部分一樣。 這是您將其作為productEnum.Where(selectorParam)調用時顯示的內容。

  2. 使用更類似SQL的語法,稱為LINQ查詢語法。 請記住,編譯器會翻譯這種類似SQL的語法,以實際調用擴展方法。

當你定義Func<Product, bool> languageFilter = prod => prod.Language == lang; ,您實際上是在定義一個lambda表達式並將其賦值給Func<Product, bool>類型的變量( languageFilter )。 Products.Where(q => q.Language == parameter); 語句完全相同,只是不是在變量中捕獲lambda表達式而是將其簡單地傳遞給擴展方法。

對於您的示例,要使用LINQ查詢語法獲得相同的結果,您可以將其編寫為類似的

from p in Products
where p.Language == parameter

(假設參數在別處定義)

在內部,linq語法被分解為擴展方法,因此在功能上沒有區別。

在你有一個Filter擴展方法的情況下,使用第一個表單可能沒有多大意義。(我認為這在你的問題中是不完整的,偶然)。 但是,我們假設您需要在Filter方法中執行一些常用的邏輯,您不希望在where子句的每個實例中反復重復。 在這種情況下,構建自定義擴展方法是有意義的,這樣您就可以重用該邏輯。

例如,假設我們只使用未過期的產品(假設您的Product對象具有isExpired屬性)。 因為,您可能會使用幾個selectorParam值進一步過濾這些未過期的產品,您可以使用:

public static IEnumerable<Product> Filter(
    this IEnumerable<Product> productEnum,
    Func<Product, bool> selectorParam)
    {
        return productEnum.Where(x => !x.IsExpired).Where(selectorParam);
    }

因此,而不是調用products.Where(x => !x.IsExpired).Where(q => q.Language == parameter)products.Where(x => !x.IsExpired).Where(q => q.Price > parameter)

你可以使用:
products.Filter(q => q.Language == parameter)products.Filter(q => q.Price > parameter)

我認為如果框架中已經存在一個擴展方法來執行您想要的操作,請使用它。 'Where'方法也是一種擴展方法,而不是你寫的方法。 我的理由是,“那些聰明的微軟人可能比以往任何時候都做得更好”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM