yield nedir nasıl kullanılır

Bilineceği üzere bir class ın foreach iterasyonuna sahip olabilmesi için IEnumerable interfacesini implement etmesi gerekmekte. IEnumerable 'ı implemente eden class bu implementle birlikte override edilmesi gereken GetEnumerator metoduna sahip olur ve bu metodun içerisini doldurduktan sonra artik bu class da foreach ile gezebilecek duruma gelir. GetEnumerator metodunu override ederken, MoveNext(), Reset() metotlarini ve Current isimli propertyleri ile ilgili logic'i handle etmemiz gerekiyordu. İşte yield sayesinde bunları yapmaktan kurtuluyoruz.  Mantigi oldukca basit ama bazi projelerde uygulamaya entegrasyonu sıkıntı çıkarabiliyor. Iste bu  sıkıntıları gidermek için C# 2.0 ile birlikte gelen yield keywordu sayesinde bu işlemlerin tumu bizim için arka planda yapilmis olacak. Senaryomuz şu şekilde olsun; geriye db de kayıtlı olan ürünleri dönen bir metodumuz var ve bu metodu yield kullanmadan ve yield kullanarak yazmaya çalışalım. Yield kullanmadan public static IEnumerable<Product> GetAllProducts() { using (var db = new DbEntity()) { var productList = from product in db.Product select product; return productList.ToList(); } }   Bu normal şartlarda kullandığımız yöntem. İlgile metodu aşağıdaki gibi çağırıp dönen listeye direk olarak erişebilirsiniz. var productList = GetAllProducts(); yield kullanarak ise şu şekilde yazabiliriz  Yield Kullanarak public static IEnumerable<Product> GetAllProducts() { using (var db = new DbEntity()) { var productList = from product in db.Product select product; foreach (var item in productList) { yield return product; } } } yield da ise şu şekilde çalışır; döngüye her girdiğinde yield return product satırında fonksiyonun çağrıldığı yere ilgili product item'ını döner yani return'ü gördü diye foreach den ve metoddan direkt çıkmaz ve listenin içindeki tüm elemanlar bitinceye kadar bu işlemi yapmaya devam eder. IL Disassambler(ILDASM) acarak code tarafında MoveNext,Reset ve Current gibi uyeler yazmamamiza ragmen yield keywordu sayesinde arka planda bunlarin yazildigini goruyoruz.  Bir diğer örnek olarak ise şunu verebiliriz;  public void Consumer() { foreach(int i in Integers()) { Console.WriteLine(i.ToString()); } } public IEnumerable<int> Integers() { yield return 1; yield return 2; yield return 4; yield return 8; yield return 16; yield return 45; } Foreach de dönerken her bir int i için IEnumerable<int> Integers() metoduna giderek değerleri bize teker teker döndürebiliyor.

C# Extension Method Kullanımı

Kelime anlamı genişletilebilir metod olan Extension Method'lar C#3.0 ile hayatımıza girmiştir ve yaptığı iş itibatiyle kullanım açısından son derece faydalı metodlardır. Tek cümleyle özetlemek gerekirse class ve struct yapılarını modify etmeden ilgili struct yada class'için extension metodlar eklememizi sağlar.  Extesion metod yazarken uymamız gereken bir kaç kural vardır. Bunlar; Extension metodlar static bir class içerisinde static olarak tanımlanmalıdır.  Extend edilecek class ilgili extension metoda metodun ilk parametresi olarak verilip önünde this keyword'ü ile tanımlanmalıdır Extension metod da tanımlı parametrelerden sadece 1 tanesi this keyword'ü ile tanımlanır Hemen bir örnek üzerinde inceleyelim. Case'imiz şu olsun; Bir tane extension metodumuz var ve bu metod integer bir değer alıp asal mı değil mi diye kontrol etsin. public static class MyExtensions { public static bool IsPrime(this int integer) { //tembellik edip implementation'ı yazmakla uğraşmadım :) return true; } } Yazdığımız metodu aşağıdaki görselde olduğu gibi kullanmak istediğimizde int tanımlı değişkenin adı"." nokta dediğimizde extensionMetod'u intellisense de görebileceğiz.  class Program { static void Main(string[] args) { int anyNumber = 123456; if(anyNumber.IsPrime()) { //asal sayı } else { //asal sayı değil } } } Heralde en güzel yanı da bu olsa gerek metodu extension tanımladığımız için sanki o metod int struct'ına içerisinde tanımlı bir metodmuş gibi direkt olarak "." nokta deyip kullanabiliyoruz.  Yukarıda ki örnekte int tipini baz alarak ilerledim ancak ihtiyaç dahilinde bütün tipler ve kendi tanımladığımız objeler içinde extension metodlar yazabiliriz. Yine örnek olarak ; bir Person class'ımız ver ve içerisinde DateTime tipinde ismi BirthDate olan bir property olsun. Bir tane GetBirthDate adında extension metod tanımlayalım ve bu metod bize parametre olarak aldığı Person objesinde bulunan BirthDate alanını return ettirsin. public class Person { public string FullName {get;set;} public DateTime BirthDate {get;set;} } public static class MyExtensions { public static DateTime GetBirthDate(this Person prs) { return prs.BirthDate; } }   Şimdi bu metodu kullanan kısmı yazalım using System; class Program { static void Main(string[] args) { Person prs=new Person(); DateTime bDAte = prs.GetBirthDate(); } } Görüldüğü gibi Extension metod kullanım alanımızı ihtiyaca göre genişletip metodlarımızı istediğimiz yerde "." nokta diyerek fıtı fıtı çağırıyoruz :)