Bu yazıya başlamadan önce, eğer okumadıysanız aşağıda yer alan, C# 3.0 ile ilgili önceden yazdığım yazıları okumanızı tavsiye ederim.
C# 3.0 ile Tanışalım - 1 : C# 3.0 Ne Getiriyor ve LINQ Projesi Nedir?
C# 3.0 ile Tanışalım - 2 : Bilinçsizce Türlendirilmiş Lokal Değişken (Implicitly Typed Local Variable) : var
Nesneye İlk Değer Atayıcı (Object Initializer)
Uygulamalarda sınıf (class) ve yapı (struct) tasarımı yapılırken genellikle yapıcı metotlardan (constructor) faydalanılır.. Yapıcı metot kullanımının amacı çoğu zaman, sınıf içerisindeki alan (field) ve özelliklere (property) ilk değerlerini vermek olur. Bu vakalar göz önüne alındığında, C# 3.0 ile birlikte artık sınıflara yapıcı metot yazılmak zorunda değildir. Nesne ilk değer atayıcı, herhangi bir yapıcı metot çağırmadan, nesne new anahtar kelimesi ile örneklenirken, erişilebilen bütün alan ve özelliklere değer atanmasını mümkün kılmaktadır.
Yapıcı metoda sahip olmayan yandaki Urun sınıfından nesne örneklemeye çalışalım :
Urun prod = new Urun { UrunId = 23, UrunAdi = "Notebook", SatisFiyati = 750 };
Yukarıda görülen yeni nesne örnekleme deseninin CIL çıktısı aşağıdaki gibidir :
CIL çıktısı dikkatle incelendiğinde, bunun önce standart bir nesne örneklemesi, ardından referans değişkeni üzerinden özelliklere yapılan değer atamalarına ait olduğu görülür. Yani arka planda Urun sınıfına yeni bir yapıcı metot yazılmamaktadır. Dilerseniz bu kodun C# karşılığını yazıp, CIL çıktıları karşılaştıralım :
Urun prod2 = new Urun();
prod2.UrunId = 23;
prod2.UrunAdi = "Notebook";
prod2.SatisFiyati = 750;
Yukarıdaki kodun CIL çıktısı incelendiğinde object initializer ile gerçekleştirilen nesne tanımlamasından farksız olduğu ortaya çıkar.

Object initializer kullanarak nesne örneklemesinin diğer detayları
Amacı sadece alanlara veya özelliklere başlangıç değeri vermek olan yapıcı metotlar yazılmayacağı için daha az kodla sınıf tasarımı tamamlanmış olur.
Başlangıç değerleri verilmiş yeni bir nesne, daha az kod yazarak elde edilmiş olur.
Object initializer kullanılarak üyelere başlangıç değeri verilmek istendiğinde Visual Studio uygulama geliştirme ortamı bize yardımcı olur. Süslü parantez ({) açıldığı anda, sınıf içerisindeki public alan ve özellikler listelenir.

C# 1.1 ve 2.0'da nitelik (attribute) kullanımına bakılacak olursa, bir nitelik bir sınıfa uygulanırken parametreleri object initializer mantığı ile verilmektedir. Bu mantık, artık bütün nesne örneklemesi için geçerlidir diyebiliriz.
Object initializer ile oluşturulan nesnelerde bilinçsizce türlendirilmiş lokal değişken (var) kullanılabilir :
var prod7 = new Urun { UrunAdi = "Ram", SatisFiyati = 80, Yas = 70 };
Object initializer kullanıldığında, sınıf içerisinde her parametre kombinasyonu için bir yapıcı metot varmış gibi nesne örneklenebilir. Aksi takdirde yapıcı metodu bir kaç aşırı yüklemek gerekmektedir. Farklı parametre kombinasyonları ile sınıfın alan veya özelliklerine başlangıç değerleri verilmek istendiğinde, C# 2.0 yaklaşımı ile her kombinasyon için yapıcı metotları aşırı yüklemek gerekir. Bu da sınıf içerisinde kod kalabalığı oluşturmaktadır. C# 3.0 yaklaşımında ise hiç yapıcı metot yazmadan istenen alan veya özelliğe özgürce değer atanabilir:
Urun prod3 = new Urun { UrunId = 5, UrunAdi = "PDA" };
Object initializer özelliğinin en faydalı olduğu yer ise isimsiz tiplerdir (anonymous types). Bir sorgu sonucunda dönen sonuç kümesinden, istenen kolonlardan oluşan yeni bir sonuç kümesi ele alınmak istendiğinde isimsiz tiplere başvurulur.
Object Initializer ile Özel Yapıcı Metotlar Çağırmak
Object initialier kullanılarak şu ana kadar tanımlanan nesneler için varsayılan yapıcı metot, arka planda her zaman çağrılır. Sınıf tanımlaması içine parametresiz yapıcı metot yazılsa da yazılmasa da, normal nesne örnekleme prosedürü hala geçerlidir ve object initializer'daki değer atamalarından önce çalışır. Bunun açık bir şekilde gösterilmesi istenirse, varsayılan yapıcı metot bilinçli olarak çağrılabilir :
Urun prod4 = new Urun() { UrunId = 42, Fiyat = 1200 };
Bir nesne örneklenirken, sınıf içerisinde tanımlanan herhangi bir özel yapıcı metot da çağrılabilir. Urun sınıfının, bütün public üyelerine değer atandığı özel bir yapıcı metot çağrılabilir, aynı zamanda object initializer ile de değer ataması da gerçekleştirilebilir:
Urun prod5 = new Urun(81,"CRT "Monitör,200) { UrunId = 92, UrunAdi = "LCD Monit”r", SatisFiyati = 400 };
Özel bir yapıcı metot çağırıp ardından nesne ilk değer atayıcı kullanmak görüldüğü gibi çok da faydalı değildir. Hem özel yapıcı metodu, hem de nesne ilk değer atayıcıyıdan birlikte faydalanmanın anlamlı olacağı kullanım şekli şudur: Nesne örneklenirken bilinmesi zorunlu olan özellikler olabilir. Bu zorunlu değerler için özel yapıcı metot yazılır; böylece nesne kullanıcısından değerinin alınması garanti edilir. Geri kalan özellkler için ise object initializer kullanılır ve istenen özelliklere başlangıç değerleri verilir:
Urun prod6 = new Urun(UrunKategori.Bilgisayar) { UrunAdi = "Ram", SatisFiyati = 80 };
Koleksiyonlara İlk Değer Atayıcı (Collection Initializer)
Bilindiği gibi dizilere, tanımlandıkları anda başlangıç değerleri verilebilmektedir. Çalışma zamanında diziye yeni elemanlar eklenemediği için koleksiyonları; koleksiyonların bazı yetersizliklerinden dolayı ise (boxing-unboxing'e maruz kalmak vb.) generic koleksiyonları tercih ederiz. Ancak koleksiyon kullanırken, ilk elemanlar belli olsa da dizilerdeki gibi tanımlama anında değer atamak mümkün değildi. C# 3.0 ile birlikte collection initializer, bu misyonu yüklenir. IEnumerable arayüzünden türemiş koleksiyonlar, eğer önceden belli elemanlara sahip ise artık bu elemanlar için arka arkaya Add metotları çağrılmak zorunda değildir. C# 3.0 derleyicisi, bu çağrımları bizim yerimize yapar.
ArrayList sehirler = new ArrayList { "İstanbul" , "Antalya" , "Ankara" , "İzmir" };
Aşağıdaki kod bloğunda ise yine koleksiyon ilk değer atayıcı kullanılmaktadır. Ancak bu sefer örneklenen koleksiyon sınıfına elemanlar atanırken nesnee ilk değer atayıcılardan faydalanılmaktadır.
List<Urun> urunListesi = new List<Urun>
{
new Urun { UrunAdi = "HardDisk" , SatisFiyati = 150 },
new Urun { UrunAdi = "Vista Premium" , SatisFiyati = 180},
new Urun { UrunAdi = "Klavye" , SatisFiyati = 50}
};