Quando utilizzare un metodo di estensione con lambda su LINQtoObjects per filtrare una raccolta?

StackOverflow https://stackoverflow.com/questions/5194

  •  08-06-2019
  •  | 
  •  

Domanda

Sto prototipando alcuni filtri di raccolta C# 3 e mi sono imbattuto in questo.Ho una collezione di prodotti:

public class MyProduct
{
    public string Name { get; set; }
    public Double Price { get; set; }
    public string Description { get; set; }
}

var MyProducts = new  List<MyProduct>
{            
    new  MyProduct
    {
        Name = "Surfboard",
        Price = 144.99,
        Description = "Most important thing you will ever own."
    },
    new MyProduct
    {
        Name = "Leash",
        Price = 29.28,
        Description = "Keep important things close to you."
    }
    ,
    new MyProduct
    {
        Name = "Sun Screen",
        Price = 15.88,
        Description = "1000 SPF! Who Could ask for more?"
    }
};

Ora se utilizzo LINQ per filtrare funziona come previsto:

var d = (from mp in MyProducts
             where mp.Price < 50d
             select mp);

E se utilizzo il metodo di estensione Where combinato con un Lambda, anche il filtro funziona:

var f = MyProducts.Where(mp => mp.Price < 50d).ToList();

Domanda: Qual è la differenza e perché usarne uno rispetto all'altro?

È stato utile?

Soluzione

LINQ si trasforma in chiamate di metodo come il codice che hai.

In altre parole, non dovrebbe esserci alcuna differenza.

Tuttavia, nei tuoi due pezzi di codice non chiami .ToList nel primo, quindi il primo pezzo di codice produrrà un'origine dati enumerabile, ma se chiami .ToList su di esso, i due dovrebbero essere uguali.

Altri suggerimenti

Come accennato d sarà IEnumerable<MyProduct> mentre f è List<MyProduct>

La conversione viene eseguita dal compilatore C#

var d = 
    from mp in MyProducts
    where mp.Price < 50d
    select mp;

Viene convertito in (prima della compilazione in IL e con i generici espansi):

var d = 
    MyProducts.
    Where<MyProduct>( mp => mp.Price < 50d ).
    Select<MyProduct>( mp => mp ); 
    //note that this last select is optimised out if it makes no change

Si noti che in questo caso semplice fa poca differenza.Il punto in cui Linq diventa davvero prezioso è in circuiti molto più complicati.

Ad esempio, questa istruzione potrebbe includere group-by, ordini e alcune istruzioni let ed essere comunque leggibile in formato Linq quando l'equivalente .Method().Method.Method() diventerebbe complicato.

A parte la differenza ToList, il numero 2 è molto più leggibile e naturale IMO

La sintassi che stai utilizzando D verrà trasformato dal compilatore nello stesso IL dei metodi di estensione.La sintassi "simile a SQL" dovrebbe essere un modo più naturale per rappresentare un'espressione LINQ (anche se personalmente preferisco i metodi di estensione).Come già sottolineato, il primo esempio restituirà un risultato IEnumerable mentre il secondo esempio restituirà un risultato List a causa della chiamata a ToList().Se rimuovi la chiamata ToList() nel secondo esempio, entrambi restituiranno lo stesso risultato in cui Where restituisce un risultato IEnumerable.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top