C# İle Generic Sınıflar Oluşturma, C# ile OOP uygulama geliştirdiğinizde generic sınıflar olmazsa olmazlardan diyebileceğimiz bir yapıdır. Tek bir generic sınıf oluşturarak belkide 10’larca sınıfta tekrar eden ve işi görecek kodları tek sınıftan halledebilceksiniz.
C# İle Generic Sınıflar Oluşturma ve Kurallar Belirleme
Örnek 1
En basit anlamda generic sınıfları anlatmaya çalışırsak varolan bir generic yapıdan örnek vermek istiyorum sıkça kullandığımız bir liste türü olan List ile T yerine istediğiniz tür objeyi geçerek listeye o türde veriler ekleyeceğinizi belirtebiliyor olası veri uyuşmazlıklarından bir nebze de olsa kurtulmuş oluyorsunuz. List türüne bir örnek verelim hemen, bu örneğimizde 5 kişinin adının saklandığı bir liste oluşturacağız.
1 2 3 4 5 6 | List<string> names = new List<string>(); names.Add("Murat"); names.Add("Muhammed"); names.Add("Hakan"); names.Add("Kasım"); names.Add("Burak"); |
List
sınıfını kullanabilmek için System.Collections.Generic
namespace’ini eklemeyi unutmayınız. Üstteki kodda List generic sınıfına string tipini verdiğimiz için Add metodunda parametre olarak string geçebileceğiz bunun haricinde başka bir tip değer geçilemez.
Örnek 2
Şimdi kendi generic sınıfımızı oluşturalım ve nasıl yapıldığı anlamaya çalışalım. Web programcılarının en çok kullandığı terimlerden biri olan Result yani sonuç kümelerinden yola çıkarak bir senaryo oluşturmaya çalışalım. Şimdi web’de her sayfada yaptığınız istekler sonucunda farklı veri kümeleri döner bu farklı veri kümeleri için farklı sınıfllar oluşturmaktansa generic bir yapı ile aynı sonuç kümesi fakat sadece geriye dönecek veri kümesi türünü generic sınıfına parametre geçerek ayarlayabiliriz. Alttaki kodda demek istediğimiz daha net anlayabilirsiniz.
Generic Sonuç sınıfımız.
1 2 3 4 5 6 | class Sonuc<T> { public string Mesaj { get; set; } public string Basarili { get; set; } public T Data { get; set; } } |
Üstteki koddada gördüğünüz gibi Sonuc sınıfı içerisindeki Basarili ve Mesaj özellikleri sabit tipte fakat Data özelliği sınıfa parametre olarak geçilen tipte dönmektedir. biz bu örneğimizde Sonuç özelliğine int tipinde bir değer verelim.
1 | var res = new Sonuc<int>(); |
Bu durumda res.Data
özelliğine sadece int türünde bir veri atayabilirsiniz.
Örnek 3
Eğer yaptığınız generic sınıfa parametre olarak geçilecek tiplerin belirli tipte olmasını istiyorsanız bunu where
anahtar kelimesi ile ayarlayabilirsiniz önceki örneğimizde yer alan Sonuc sınıfı ile devam edecek olursak Sonuc sınıfına parametre olarak sadece class türünde veri ayarlanabileceğiniz alttaki gibi belirtebiliyoruz böylelikle class türü dışındaki hiçbir türü parametre olarak geçemeyeceksiniz.
Örnek 2’deki kodumuzu where anahtar kelimesini ekleyerek sadece class türünde verinini parametre olarak geçilebileceğini belirttik ve Parametre olarakda Kisi adındaki sınıfı geçtik.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var res = new Sonuc<Kisi>(); } } class Kisi { public string Ad { get; set; } public string Soyad { get; set; } } class Sonuc<T> where T : class { public string Mesaj { get; set; } public string Basarili { get; set; } public T Data { get; set; } } } |
Örnek 4
Generic sınıf oluşturduğunuzda parametre ismi olarak istediğiniz ismi verebilirsiniz tek parametreli generic sınıflarda standart olarak T kullanılmaktadır fakat birden fazla parametre geçileceği durumlarda geçilen parametrenin ne olduğunu belirtmeniz oluşturduğunuz sınıfı kullanacak kişinin ne amaçla parametre olarak geçtiğini bilmesi açısından önemlidir. Şimdiki örneğimizde yine üstteki son iki örneğimizde olduğu gibi Sonuc sınıfı üzerinden devam ederek örnek verelim. Burada 3 özelliğinde generic olarak parametre yolu ile oluşmasını sağlayalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var res = new Sonuc<Kisi, bool, string>(); } } class Kisi { public string Ad { get; set; } public string Soyad { get; set; } } class Sonuc<TData, TBasarili, TMesaj> where TData : class { public TMesaj Mesaj { get; set; } public TBasarili Basarili { get; set; } public TData Data { get; set; } } } |
Buradaki TBasarili default olarak tipi bool ayarlanabilir generic olarak geçmenin bir esprisi yok sadece isterseniz bütün nesneler için generic tip ayarlayabileceğinizi gösterebilmek adına bu örnekte TBasarili diye generic olarak Basarili özelliğinin tip ayarlamasını yapıyoruz.
Birden fazla where kullanımı
Eğer birden fazla where kullanarak generic sınıfa parametre olarak geçilen türlerin neler olacağını sınırlamak isterseniz o zaman yan yana arada ayraç olmadan kullanabilirsiniz örnek olarak Mesaj özelliğininde Data özelliğinde olduğu gibi sadece class türünden veri geçilebileceğini alttaki gibi belirtebilirsiniz.
1 | class Sonuc<TData, TBasarili, TMesaj> where TData : class where TMesaj: class |
Defaut costructor’ı olan bir class olması için kural belirleme
Bu kural özellikle şu işe yaramaktadır örnek veriyorum Generi olan beklediğiniz nesnenin costructor’ı private olarak belirlenip nesne oluşturulmaması için kapatılmış olabilir yada default consturtor parametreli constructor ayarlanarak ezilmiş olabilir bu durumda bu class’ı generic olarak alıp new keyword’ü ile oluşturmak istediğinizde runtime exception fırlatacaktır. Tam olarak bu sorunu aşmak için yapmanız gereken where kısmında new() ifadesi ile default ve public bir consturctor’a sahip bir class geçebilirsiniz şeklinde kural belirleyerek runtime exception’ın önüne geçmiş olursunuz.
Hemen bu durum ile ilgili basit bir örnek yapalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class Person { public string Name { get; set; } = "Murat"; } /* Buradaki ISample adındaki generic tipin where kısmında 2 adet kural belirlendiğini görüyoruz bunlardan biri class olmak zorunda ve default constructor'ı olmak zorunda denilen new() keword'u kullanılmıştır. */ public class PersonManagement<ISample> where ISample : class, new() { public ISample GetInstance() { return new ISample(); } } var management = new PersonManagement<Person>(); var person = management.GetInstance(); |
Gördüğünüz gibi kod içerisindeki açıklamada belirttiğimiz gibi ISample adındaki generic parametremiz için 2 adet kuralımız yer alıyor ilki generic parametre için geçilen türün class olması gerektiğini söylüyoruz diğeri ise new() keyword’u ile bu verilen türden bir instance alabilecek şekilde public default constructor’a sahip olması gerektiğini belirtiyoruz eğer class’ınız içerisinde constructor tanımı ve access modifier ayarlaması hiç yoksa o zaman varsayılan olarak public şeklinde default constructor tanımı yer aldığından ayrıca birşey yapmanıza gerek yoktur.
📚 Kaynaklar
Diğer C# ile İlgili Makaleler
- C# Switch Case Yapısı Kullanımı
- C# 7.0 İle Beraber Gelecek Yenilikler
- C# Operatör Aşırı Yükleme(Operator Overloading)
- C# Yapı ve Sınıf arasındaki farklılıklar
✍ Generic Sınıflar Oluşturma makalesi için lütfen olumlu-olumsuz tüm görüşlerinizi bana yorum yada mail yolu ile iletmeyi ihmal etmeyin.
🔗 Generic Sınıflar Oluşturma makalesi için sosyal medya kanallarından makaleyi paylaşarak destek olursanız çok sevinirim.
👋 Bir sonraki makalede görüşmek dileğiyle.
Elinize sağlık bende konunun temelini anlamak için yok yararlı buldum.
Teşekkür ederim, yararlı bulmanıza sevindim.
Teşekkürler, faydalı oldu.
Rica ederim faydalı olmasına sevindim.
çok yararlı oldu teşekkürler
Rica ederim ben de beğenmenize sevindim.