C# 3.0 Object Initializer Özelliği

C# 3.0 object initialize etmek için kodda kısaltma sağlayacak bir yenilik sunuyor. Hemen hergün aşağıdaki gibi kod yazmamız gerekmez mi?

Personel UygulamaGelistirici = new Personel(); UygulamaGelistirici.Id = 42; UygulamaGelistirici.AdSoyad = “Engin Polat”; UygulamaGelistirici.Birim = “NTV - Yeni Medya”;</pre> Personel sınıfından yeni bir örnek oluşturduktan sonra, sınıfın özelliklerinden ihtiyacımız olanlara atamalar yapmaya başlarız.

Eğer Personel sınıfının constructor‘ı olsaydı ve bu özelliklerin atamalarını yapsaydı, tek bir satırda, hem Personel sınıfının yeni bir örneğini UygulamaGelistirici değişkenine oluşturmuş, hem de bazı özelliklerin değerlerini atamış olabilirdik.

Fakat, Personel sınıfının constructor‘ını yazamadığımız durumlarda veya constructor‘da parametreler ile almak için çok fazla özellik olduğu durumlarda bu yöntemi kullanamayız.

C# 3.0 ile birlikte Object Initializer denilen yeni bir kodlama tekniği tanıtıldı.

Hemen yukarıdaki örneği bu teknik ile yazalım;

Personel UygulamaGelistirici = new Personel() { Id = 42, AdSoyad = "Engin Polat", Birim = "NTV - Yeni Medya" };

Gördüğünüz gibi, kodlama bizim için kolaylaşıyor.

Object Initializer içerisinde sadece özelliklere atama yapabiliyoruz, method çağrımı vs. yapılamıyor.

Eğer sınıfın özellikleri başka sınıflardan örnekler istiyorsa, Object Initializer nasıl yazabiliriz? Aşağıdaki gibi yazabiliriz;

VeritabaniSorgulayici dbSorgu = new VeritabaniSorgulayici() {
    Connection = new SqlConnection("..ConnectionString.."),
    Command = new SqlCommand("..Sorgu..")
};


C# Obsolete Attribute

Yaklaşık olarak .Net Framework içerisinde binlerce class ve binlerce class içerisinde milyonlarca method vardır.

Her yeni .Net Framework versiyonunda bu class‘ların ve method‘ların bir kısmı yeni yöntemler / yeni teknikler ile baştan yazılıyor.

Bazen bu değişiklikler o kadar büyük oluyor ki, ilgili class veya method yeni bir isimle baştan yazılıyor ve eskisinin artık kullanılmaması öneriliyor.

Önceki Framework versiyonlarında yanlış konumlandırdıkları class veya method‘ları taşıdıkları durumlarda da aynı durum geçerli.

Geriye yönelik uyumluluktan dolayı, kullanılmaması önerilen class veya method‘lar üç versiyon daha yerinde durmaya devam eder.

Ama derleme zamanında uygulama geliştiriciye, ilgili class veya method‘un Obsolete olduğunu bildirir ve kodunu güncellemesini ister.

Bu özellik Obsolete Attribute sayesinde sağlanır.

Eğer biz de yazdığımız projelerimizde çeşitli class veya method’ları Obsolete yapmak istersek, aşağıdaki kodda gözüktüğü gibi yapabiliriz;

[Obsolete] public class EskimisClass { /// }</pre> veya

[Obsolete("Bu method v4.5 versiyonundan itibaren kaldırılacak, lütfen yerine Ntv.YeniMedya.Veritabani sınıfında bulunan Baglan() methodunu kullanın. Ayrıntılı bilgi için http://www.xyz.com/Baglan sayfasına bakabilirsiniz")]
public void VeritabaniBaglan()
{
    ///
}

Yukarıdaki kodda bulunan *VeritabaniBaglan()* method'unu kullanırken ve projemizi derlerken aşağıdaki ekranlar ile karşılaşırız;

![Obsolete Method](/assets/uploads/2010/01/Obsolete_1.png "Obsolete_1")

![Obsolete Method Error](/assets/uploads/2010/01/Obsolete_2.png "Obsolete_2")

C# Rezerve Methodlar - Reserved Methods

C# dilinin bazı yetenekleri, aslında uygulama geliştiricilerin göremedikleri method’lardan gelmektedir.

Eğer geliştirdiğiniz uygulamanın assembly’lerini ILDASM tool’u ile açıp incelerseniz, bu method çağrılarını görebilirsiniz.

Eğer bilerek veya yanlışlıkla bu method’lardan birisi ile aynı isme sahip method oluşturmaya çalışırsanız, derleme anında (compile-time) hata alırsınız.

Bu rezerve method isimlerini inceleyelim;

Özellikler (Properties) için Rezerve Methodlar;

Class veya Struct‘larınıza eklediğiniz özellikler, derleme zamanında

T add_{OzellikAdi}

  • void set_{OzellikAdi}(T value)*

şablonunda iki method’a dönüştürülür. Class veya Struct‘ınıza bu şablona uyan method ekleyemezsiniz.

Indexer’lar için Rezerve Methodlar;

Indexer’larınız derleme zamanında

T get_Item(Parametre)

  • void set_Item(Parametre, T value)*

şablonunda iki method’a dönüştürülür.

Yıkıcılar (Destructors) için Rezerve Methodlar;

Class veya Struct‘ınıza eklediğiniz Destructor kodu derleme zamanında

void Finalize()

method’una dönüştürülür. Class veya Struct‘ınıza Finalize() method’u eklemeye çalıştığınızda derleme zamanında uyarı alırsınız.

Olaylar (Events) için Rezerve Methodlar;

Olaylarınız için derleme zamanında kodunuza

void add_{EventAdi}(T callback)

  • void remove_{EventAdi}(T callback)*

methodları eklenir.

C# Partial Method Desteği

C# 3.0 ile gelen partial keyword’u sayesinde partial class tanımlayabiliyoruz.

partial keyword’unun pek bilinmeyen bir kullanım alanı ise method‘lardır.

partial class tanımlayabildiğimiz gibi partial method‘da tanımlayabiliyoruz.

partial class‘ları tanımlamamızdaki en büyük fayda, kod üreticiler olmuştur. partial method tanımlamanın güzelliği de işte burada. Bir kod üreticisi ile otomatik olarak kod ürettirirken, partial method‘lar ürettirebiliriz.

Eğer üretilmiş partial method‘u uygulamazsanız, ilgili partial method‘u çağıran kod parçaları hata vermiyor.

Basitçe, uygulanmamış partial method çağrıları derleme (compile) sırasında yok sayılıyor.

Ama partial method‘lar için bazı kısıtlamalar ve kurallar var;

  • partial method’ların geri dönüş tipi herzaman void olmalıdır
  • partial method’lar out parametreler alamazlar, ama ref parametreler alabilirler
  • partial method’lar extern olamazlar
  • partial method’lar erişim belirleyici alamazlar, çünkü herzaman private erişim belirleyicisine sahiptirler
  • partial method’lar virtual olamazlar
  • partial method’lar static olabilir
  • partial method’lar generic olabilir
  • partial method’lara delegate bağlanamaz, çünkü partial method’un çalışma zamanında (runtime) var olacağı garanti değildir Bu bilgilerden sonra örnek bir class yazalım;

public partial class DataAccessLayer { partial void ResetConnection(); }

public partial class DataAccessLayer { partial void ResetConnection() { ///Connection’ı resetleyen kod }

public void Reset()
{
    ResetConnection();
} }

Gördüğünüz gibi, Reset() isminde public bir method yazmam gerekti. Çünkü, ResetConnection() method‘u partial olduğu için private erişim belirleyicisine sahip.

Eğer yukarıdaki kodun exe/dll dosyasına ILDASM tool’u bakarsak, DataAccessLayer.ResetConnection() private method’unu ve Reset() method‘u içerisinde bu method’u çağıran kod parçasını görürüz.

Eğer ResetConnection() method’unu uyguladığımız kod parçasını sildikten sonra, ILDASM ile bakarsak, DataAccessLayer.ResetConnection() private method’unun bulunmadığını ve Reset() method’unda bu method’u çağıran kod parçası olmadığını görürüz.

Böylece çalışma zamanı hatası almayız.

C# Erişim Belirleyiciler - Access Modifiers

Öncelikle erişim belirleyicilerin (access modifiers) nerelere uygulandığını bilmemiz lazım; C# projesinde tanımlanmış tüm varlıklara uygulanabilir, buna class, struct, function, method, property ve class seviyesindeki tüm değişkenler dahildir.

Peki, neden erişim belirleyicilere ihtiyaç duyarız?

Çünkü, uygulamamızda kullandığımız varlıkların bulundukları kod bloğunun dışından erişilip/erişilemeyeceğini belirlemek isteriz.

C# dilinde tanımlı erişim belirleyiciler (access modifiers);

public : public olarak tanımlanan öğe, kod bloğunun içinde ve dışında tamamen erişilebilirdir. Yani, hiçbir kısıtlama yoktur.

protected : protected olarak tanımlanan öğe, sadece tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilirdir.

internal : internal olarak tanımlanan öğe, bulunduğu assembly’nin (Dll veya Exe dosyası) içinde erişilebilirdir. Dll veya Exe dosyasının içerisinde erişim için kısıtlama yoktur, ama dışarıdan erişilemez.

protected internal : protected internal erişim belirleyicisi, protected ve internal erişim belirleyicilerinin VEYA (OR) işlemiyle birleştirilmiş halidir. protected internal olarak tanımlanmış öğe, tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilir. Ayrıca, aynı assembly içinde olmasalar dahi, tanımlandığı class’tan türetilmiş diğer class’ların içinde de erişilebilirdir.

private : private olarak tanımlanan öğe, sadece tanımlandığı class’ın içerisinde erişilebilirdir. En katı erişim belirleyicidir.

Aslında CLR içinde tanımlı bir erişim belirleyici daha vardır. FamilyAndAssembly olarak bilinir. C# kelimeleri ile benzetmeye çalışırsak, protected VE (AND) internal erişim belirleyicisidir. C# dili bu erişim belirleyicisini desteklemez, eğer kullanmanız gerekiyorsa, C++ ve direk IL yazmanız gerekmektedir.

class veya struct‘lar ya public, ya da internal olabilir, varsayılan olarak internal erişim belirleyicisine sahiptirler.

Varsayılan olarak class içerisinde tanımlı öğeler private erişim belirleyicisine sahiptirler.

struct içerisinde tanımlı öğeler public, internal veya private olabilirler. struct‘lar türetmeyi desteklemediği için protected ve protected internal erişim belirleyicisine zaten ihtiyaçları yoktur.

Engin Polat hakkında

Chief Architect, Microsoft RD, Microsoft MVP

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 458

Creative Commons Lisansı