Wann sollte eine Erweiterungsmethode mit Lambda über LINQtoObjects verwendet werden, um eine Sammlung zu filtern?
Frage
Ich erstelle Prototypen einiger C#-3-Sammlungsfilter und bin darauf gestoßen.Ich habe eine Sammlung von Produkten:
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?"
}
};
Wenn ich nun LINQ zum Filtern verwende, funktioniert es wie erwartet:
var d = (from mp in MyProducts
where mp.Price < 50d
select mp);
Und wenn ich die Where-Erweiterungsmethode in Kombination mit einem Lambda verwende, funktioniert der Filter auch:
var f = MyProducts.Where(mp => mp.Price < 50d).ToList();
Frage: Was ist der Unterschied und warum sollte man sie übereinander verwenden?
Lösung
LINQ verwandelt sich in Methodenaufrufe wie der Code, den Sie haben.
Mit anderen Worten: Es sollte keinen Unterschied geben.
Allerdings rufen Sie in Ihren beiden Codeteilen nicht .ToList im ersten auf, sodass der erste Codeteil eine aufzählbare Datenquelle erzeugt, aber wenn Sie .ToList darauf aufrufen, sollten die beiden gleich sein.
Andere Tipps
Wie erwähnt wird d sein IEnumerable<MyProduct>
während f ist List<MyProduct>
Die Konvertierung erfolgt durch den C#-Compiler
var d =
from mp in MyProducts
where mp.Price < 50d
select mp;
Wird konvertiert in (vor der Kompilierung in IL und mit erweiterten Generika):
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
Beachten Sie, dass es in diesem einfachen Fall kaum einen Unterschied macht.Linq wird in viel komplizierteren Schleifen wirklich wertvoll.
Diese Anweisung könnte beispielsweise Group-Bys, Orders und einige Let-Anweisungen enthalten und dennoch im Linq-Format lesbar sein, wenn sie äquivalent ist .Method().Method.Method()
würde kompliziert werden.
Abgesehen vom ToList-Unterschied ist Nr. 2 meiner Meinung nach viel lesbarer und natürlicher
Die Syntax, die Sie verwenden D wird vom Compiler in dieselbe IL wie die Erweiterungsmethoden umgewandelt.Die „SQL-ähnliche“ Syntax soll eine natürlichere Möglichkeit zur Darstellung eines LINQ-Ausdrucks sein (obwohl ich persönlich die Erweiterungsmethoden bevorzuge).Wie bereits erwähnt, gibt das erste Beispiel aufgrund des Aufrufs von ToList() ein IEnumerable-Ergebnis zurück, während das zweite Beispiel ein List-Ergebnis zurückgibt.Wenn Sie den ToList()-Aufruf im zweiten Beispiel entfernen, geben beide das gleiche Ergebnis zurück, da Where ein IEnumerable-Ergebnis zurückgibt.