Hiljuti leidsin ühest ajaveebist huvitava artikli nimega “If you are using a loop, you’re doing it wrong” ning autoriks on Chuck Jazdzewski. Selle peamiseks ideeks on kasutada LINQ päringuid tsüklite asemel ja pigistada välja C# 3.0 uutest võimalustest sellest piisavalt, et tsüklit ei ole vajagi.
Ainuke küsimus, mis sellega kerkis on see, et kas koodi loetavus paraneb sellega või halveneb.
foreach (var project in projects)
{
if (project.EstimatedTime > 10)
yield return project;
}
või
var result = from project in projects
where project.EstimatedTime > 10
select project;
Lugeda tundub selliseid lihtsamaid päringuid veidi parem. Katsetuste käigus selgus, et ilma tsükliteta päris edukalt nagu ikka ei saa – ekraanile tuleks ka midagi trükkida. Seega mängisin veidi ning jõudsin järgmise tulemuseni:
int[] list = new int[] {1,2,3,4,5,6,7,8,9,10};
(
from value in list
where value % 2 == 1
select value
).Do(x => Console.WriteLine(x))
Kuna siin seisneb peamine probleem selles, et select‘is ei anna lihtsalt käivitada mingit meetodit, siis tuleb lisada juurde laiendusmeetod IEnumerable<T>-le nimega Do:
static class Extension
{
public static IEnumerable<T> Do<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T value in list)
{
action.Invoke(value);
}
return list;
}
}
Sellele saab kenasti veel mõned overload‘id juurde teha ning nimekirja tagastamine on puhtalt selleks, et saaks teha list.Do(…).Do(…)… Alternatiiv sellele oleks ka teha staatiline klass:
class Command
{
static public Action<T> Execute<T>(Action<T> action, T value)
{
action.Invoke(value);
return action;
}
}
Ning siis saame pärida järgnevalt;
(
from value in list
where value % 2 == 1
select Command.Execute((x => Console.WriteLine(x)), value)
).ToList();
Siinjuures peab kindlalt kutsuma lõpus välja mingisuguse meetod, mis sunnib LINQ päringut käivitama.
Ma ei ole kindel, et selline lähenemine oleks kõige mõistlikum, kuid siiski üks võimalikke. Hea oleks kuulda, mida teised arvad sellisest vaatenurgast. Lisaks oleks kasulik teha sellele kiirusetest ja vaadata ka milline IL koodis välja näeb.
Loe veel sarnastel teemadel:
- Kaitsev programmeerimine, 9. juuli
- Ebameeldivad erijuhud, 21. jaanuar
- Rubylik C#: Monkeypatching, 27. oktoober
- Vaesed inimesed, 28. jaanuar
- Ruby väärtuslikkus, 27. aprill
5 kommentaari
1
Ma arvan, et seda ettekirjutust sõnasõnalt järgida on liiast. Eesmärk on ikkagi kood kõige selgemalt ja ülevaatlikumalt teisele inimlugejale mõistetavaks teha.
Oma viimases projektis kasutan väga ulatuslikult LINQt, ja just tihti IEnumerable laiendusmeetodeid selle query-keele asemel, olenevalt kumb parasjagu loetavam tundub. Tavaliselt on määravaks see, kas päringu lõpus selectitakse midagi uut ja huvitavat või mitte: kui ei, siis tekib kaks mittevajalikku rida alguses ja lõpus:
from x in xs
where tingimused
select x
Näiteks esimene näide oleks minuarust kõige selgem nii:
var result = projects.Where(p => p.EstimatedTime > 10);
Kusjuures kui tegu ei ole suure (näiteks mitme listi üheaegse töötlemisega) avaldisega, siis ühetähelised muutujad soodustavad loetavust, mitte ei sega seda.
Sinu teksti teises pooles toodud leiutis tegevuste käivitamiseks tundub lausa hirmus..
( from value in list where value % 2 == 1 select Command.Execute((x => Console.WriteLine(x)), value) ).ToList();
peidab sügavale rea keskele ära kogu info selle kohta, mis tehakse! Arvan, et siin on ikkagi kõige parem ja loetavam kasutada lihtsalt foreach loopi:
foreach (int i in list.Where(x => x % 2 == 1))
Console.WriteLine(i);
Teine võimalus oleks kasutada juba olemasolevat Listi (aga mitte IEnumerable) meetodit ForEach, mis võtab Action tüüpi funktsiooni, mida iga elemendiga käivitada.
list.Where(x => x % 2 == 1).ToList().ForEach(x => Console.WriteLine(x));
Mõlemad on veidi selgemad ja lühemad, sest nendes ei ole mitmeid sulge ja üksteise sisse peidetud avaldisi – saab lugeda vasakult paremale ja ülevalt alla. Aga isiklikult pean siin kõige selgemaks ikkagi foreach loopi.
mattias
11:00, 16. aprill
2
Jah, see näide oli toodud juba olemasolevaid meetodeid kasutadaes.
Selle ForEachi (Do nime all) oled juba valmis kirjutanud
mattias
12:15, 16. aprill
3
Küllap tuleb mõne aja pärast APIsse. C# meeskond võiks kuhugi üles panna ka hääletuse teemal, milliseid funktsioonidest puudust tuntakse, sest puudu on ka palju teisi kasulikke laiendusmeetodeid, mis võiks ise kirjutamise asemel standard librarys olla.
Näiteks minimaalse väärtusega objekti tagastamine (mitte selle väärtuse), kus objekt -> väärtus funktsioon on parameetriks, erinevad tükeldamised jms.
mattias
13:08, 16. aprill
4
Viimane variant on juba suhteliselt mõnus,
list.Where(x => x % 2 == 1).ToList().ForEach(x => Console.WriteLine(x));
kuigi mind häirib selle juures ToList() meetod. Veel parem oleks midagi sellist:
list.Where(x => x % 2 == 1).ForEach(x => Console.WriteLine(x));
Marek Tihkan
11:32, 16. aprill
5
“Selle ForEachi (Do nime all) oled juba valmis kirjutanud”
Seda ma panin tähele isegi. Kuigi imestan, et miks seda praeguses API-s pole.
Marek Tihkan
12:28, 16. aprill
Lisa kommentaar
KAIZEN FEED
Telli endale Kaizeni uudisvoog
KOMMENTAARIDE FEED
Telli endale kommentaaride voog
KAIZEN TWITTER
Lühiuudised Kaizeni autoritelt
KAIZEN FACEBOOK
Liitu Kaizeniga
MIS ON KAIZEN?
Kaizen on Saiku tarkvaraarendusealane blogi, kus kirjutame erinevatest lähenemistest meisterlikule tarkvaraarendusele.
KATEGOORIAD
- .NET (18)
- Analüüs/Arhitektuur (11)
- Arendus (66)
- Ettevalmistus (1)
- Juhtimine (2)
- Varia (24)
SILDIPILV
- .NET (41)
- ilus kood (23)
- Arendus (23)
- C# (20)
- Analüüs/Arhitektuur (14)
- Testimine (10)
- raamat (8)
- Ruby (8)
- projektijuhtimine (8)
- printsiibid (6)
- produktiivsus (5)
- ReSharper (5)
- PHP (5)
- NHibernate (4)
- objekt-orienteeritud (4)
- pidev integratsioon (4)
- Viited (4)
- agile (4)
- Java (4)
- Geekdinner (4)
- lean (4)
- raamatukogu (4)
- CI (3)
- Cruise Control.NET (3)
- Robert C. Martin (3)
- scrum (3)
- iteratsioon (3)
- suhtlus (3)
- jQuery (2)
- TechEd 2008 (2)
- Visual Studio (2)
- valideerimine (2)
- intervjuu (2)
- tööpakkumised (1)
- analüüs (1)
- ASP.NET (1)
- ümberstruktureerimine (1)
- üritus (1)
- CodeRush (1)
- dokumentatsioon (1)
- Kent Beck (1)
- LINQ (1)
- Martin Fowler (1)
- Moq (1)
- Rhino Mocks (1)
- stackoverflow (1)
- võltsitud objektid (1)
- Whiteboard Wednesday (1)
- hindamine (1)
- tarkvara kvaliteet (1)
- ajagraafikud (1)
- Saiku (1)
- koolitus (1)
- tagasivaate (1)
- koosolek (1)
- dünaamilised keeled (1)
- staatilised keeled (1)
- FluentNHibernate (1)
- facebook (1)
- aastapäev (1)
- Rake (1)
- Oredev 2008 (1)
- toyota way (1)
- raiskamine (1)
- NDepend (1)
- podcasts (1)
- väle tarkvaraarendus (1)
- raido tonts (1)
- minimal marketable feature (1)
- kasutajalugu (1)
- twitter (1)
- Joomla! (1)
- MVC (1)
- andmebaas (1)
- versioonimine (1)
- diskussioon (1)
- regulaaravaldised (1)
- motiveerimine (1)
- mõõdikud (1)
- agileestonia (1)
- riistvara (1)
- koolitused (1)
- kujundus (1)
- kodulehed (1)
- veeb (1)
