C# Generic Base Class Constraint
Bu yazımda C#’ta Generic Base Class Constraint’ten bahsedeceğim.Generic Base Class Constraint ile Generic sınıfımızın hangi veri türlerini kabul edeceğini kısıtlayabiliriz.Generic sınıflarda kısıtlama yapabilmek için “<T> where T:Tip” imzasını class imzasına eklemeliyiz.
Şimdi örneklere başlamadan önce A,B,C ve Gen adında dört adet sınıf oluşturalım.B sınıfı A sınıfından kalıtım alsın.
---A.cs--- class A { public string MerhabaDunya() { return "Merhaba Dünya"; } } ---B.cs--- class B:A { public string Merhaba() { return "Merhaba"; } } ---C.cs--- class C { }
Yukarıda gördüğünüz gibi, A.cs sınıfında MerhabaDunya() metodu ve B.cs sınıfında Merhaba() metodu bulunmaktadır.
Şimdide Gen.cs adında Generic sınıfımızı oluşturalım.
class Gen<T> { }
Şimdi yapmak istediğim senaryoyu açıklıyorum.Bu Gen.cs adındaki Generic sınıfımızdan üretilen nesnelerde alacağı tipler, sadece A tipi olsun.
class Gen<T> where T : A { }
Yukarıdaki Generic sınıf artık A tipinden değerler almaktadır.Başka tipten değer almayacaktır.
Gen<A> gen1 = new Gen<A>(); //Doğru Gen<B> gen2 = new Gen<B>(); //Doğru Gen<C> gen3 = new Gen<C>(); //Yanlış
Yukarıda sadece A tipinden değer alacak dediğim halde B tipinide kabul etmiştir.Ama C tipini kabul etmemiştir.Bunun sebebini azcık düşünüp bulabiliriz.B sınıfı A sınıfından türediği için, çok biçimlilik sayesinde B tipide geçerli oluyor.Sebebi budur.
Şimdi aşağıdaki Generic sınıfını tekrardan inceleyelim.
class Gen<T> where T : A { }
Yukarılarda bahsettiğimiz gibi bu Generic sınıfın tipi sadece A ve A dan türeyen sınıflar olabilir.
Şimdi sizlere birşey göstermek istiyorum.
class Gen<T> where T : A { T mesaj; public void Mesaj() { mesaj.MerhabaDunya(); } }
Yukarıdaki kod bloğunu siz incelerken ben aşağıda ne anlatmak istediğimi açıklayayım.
Bu Generic sınıfın alacağı parametresine gelecek olan tipin A tipinden ve A dan türeyen bir tipten olduğunu biliyoruz.Kesin eminiz.Yani yukarıdaki yapıda “T” kesinlikle A dır(A tipidir.).T tipinden(yani A tipinden) “mesaj” adında bir field oluşturuluyor.Mesaj() metodu içinde bu fieldı yazıp nokta dediğimizde A sınıfı içindeki MerhabaDunya() metodunu görüyoruz.Bunun sebebi,derleyicininde bundan emin olmasıdır.Yukarıdaki Constraint(kısıtlayıcı) bize, T nin A olduğunu söylüyor.Ee haliyle derleyicide “madem ben bunun A olduğunu biliyorum, hiç uzatmayım T tipinden bir referansa A’nın elemanlarını atıyım” diyor.Çünkü T tipinden değişken dediğimiz A tipinden bir değişkendir.
class Gen<T> where T : B { T mesaj; public void Mesaj() { mesaj.MerhabaDunya(); mesaj.Merhaba(); } }
Eğer yukarıdaki sınıfı incelerseniz, bu seferde T nin sadece B tipinden olacağını söylüyoruz.Ve T tipinden(aslında B tipinden) olan mesaj referansına nokta dediğimizde, B.cs sınıfındaki Merhaba() metoduyla karşılaşıyoruz.Ve ayriyetten A.cs sınıfındaki MerhabaDunya() sınıfınıda görüyoruz.Bunun sebebi nedir? diye sorarsanız eğer,konumuzun ek bir teferruatı değildir.Sadece programlamada Kalıtım konusunu biliyorsanız ne demek istediğimi anlayacaksınız.B sınıfı A sınıfından kalıtım aldığı için,B sınıfı nesnesi veya referansı üzerinden, hem kendi elemanlarını hemde kalıtım aldığı sınıfın(base class) elemanlarına ulaşılır.
Bu yazımında sonuna gelmiş olduk.Umarım ne demek istediğimi anlamışsınızdır 🙂
İyi çalışmalar…