Buraya bir adım atacağım. Kodun seçici ayrıntılarına yoğunlaşıyorsunuz ancak büyük resmi kaçırıyorsunuz. Örnek döngülerinize bir göz atalım:
int offset = 0;
while(true)
{
Record r = Read(offset);
if(r == null)
{
break;
}
// do work
offset++;
}
Bu kodun anlamı nedir ? Anlamı "bir dosyadaki her kayıt için biraz çalışma". Ancak kod böyle görünmüyor . Kod "ofseti koru. Bir dosya açın. Son koşulu olmayan bir döngü girin. Bir kayıt okuyun. Boşluk testi yapın." Bütün bunlar işe başlamadan önce! Sormanız gereken soru şudur: " Bu kodun görünümünü anlamıyla eşleştirebilir miyim? " Bu kod şöyle olmalıdır:
foreach(Record record in RecordsFromFile())
DoWork(record);
Şimdi kod niyetinde olduğu gibi okunur. Mekanizmalarınızı anlambiliminizden ayırın . Orijinal kodunuzda, mekanizmayı - döngünün ayrıntıları - anlambilim ile - her kayıt için yapılan işi karıştırırsınız.
Şimdi uygulamak zorundayız RecordsFromFile(). Bunu uygulamanın en iyi yolu nedir? Kimin umrunda? Kimsenin bakacağı kod bu değil. Temel mekanizma kodu ve on satır uzunluğunda. İstediğiniz gibi yazın. Buna ne dersin?
public IEnumerable<Record> RecordsFromFile()
{
int offset = 0;
while(true)
{
Record record = Read(offset);
if (record == null) yield break;
yield return record;
offset += 1;
}
}
Artık tembel olarak hesaplanmış bir kayıt dizisini manipüle ettiğimize göre, her türlü senaryo mümkün hale geliyor:
foreach(Record record in RecordsFromFile().Take(10))
DoWork(record);
foreach(Record record in RecordsFromFile().OrderBy(r=>r.LastName))
DoWork(record);
foreach(Record record in RecordsFromFile().Where(r=>r.City == "London")
DoWork(record);
Ve bunun gibi.
Bir döngü yazdığınızda, kendinize "bu döngü bir mekanizma veya kodun anlamı gibi mi okuyor?" Diye sorun. Cevap "bir mekanizma gibi" ise, o mekanizmayı kendi yöntemine taşımaya çalışın ve anlamı daha görünür hale getirmek için kodu yazın.