2.5 KiB
+++ title = "linq" draft = false tags = [ "", "Users", "jefklak", "Downloads", "pages", "code", "csharp", "linq" ] date = "2014-01-29" +++
Collections, Iterating, ???, Linq (profit)
yield hocus pocus
Zie The implementation of iterators in C# - wordt uitgelegd hoe yield
door de compiler geïnterpreteerd wordt.
Hiermee is het mogelijk om heel snel uw eigen IEnumerable
te maken.
“yield”, [...] which allows you to quickly write iterators without worrying about preserving state.
Folding, selecting, etc
Closing over the loop variable
Main article: http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
Opgelet met foreach
en de manier waarop die geïmplementeerd is (onder C# 5):
{
IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator();
try
{
int m; // OUTSIDE THE ACTUAL LOOP
while(e.MoveNext())
{
m = (int)(int)e.Current;
funcs.Add(()=>m);
}
}
finally
{
if (e != null) ((IDisposable)e).Dispose();
}
}
de variabele m
verandert constant. Wanneer we in een loop dan een delegate
gebruiken die de variabele uitleest, krijgen we op moment van executie slechts de laatste waarde!
var values = new List<int>() { 100, 110, 120 };
var funcs = new List<Func<int>>();
foreach(var v in values)
funcs.Add( ()=>v );
foreach(var f in funcs)
Console.WriteLine(f()); // print 120, 120, 120, whoops??
side-effects
Zie ook foreach vs ForEach: LINQ
is ontwikkeld om side-effect free te werken, dit wil zeggen dat er altijd een nieuwe collectie aangemaakt wordt. De volgende code is niet voldoende om in een method een lijst te sorteren:
private void sortMe(IEnumerable<string> toSort) {
toSort.ToList().Sort(); // ToList() returns a new list! as it should be
}
naming
- Gebruik
Select()
in plaats van de JStransform()
. Aggregate
is een nativefoldLeft
- gebruikReverse
om van achter naar voor te beginnen.All
retrourneert een boolean en is om te controleren of er elementen in een collectie zitten, niet om te transformen of te loopen!