Generic kavramı C#2,0 ile beraber artık hayatımıza girmeye başlamıştır.
Performans konusunda büyük avantajlar sağlayan generic sınıfların temel
özelliklerinden daha önce sitemizde bahsetmiştik. Bu makalemizde generic sınıfların
oluşturulması, türetilmesi, metotların tanımlanması vb konuları aydınlatmaya
çalışacağız. Generic Sınıflar temel olarak normal sınıflar ile aynı özellikleri
göstermektedir. Generic sınıfların normal sınıflardan farkı, kullanılacak olan
tiplerin sınıf tanımlama aşamasında belirtilmesidir. Aşağıda normal bir sınıf
ile generic sınıf arasındaki tanımlama farkını görebilirsiniz
using System;
namespace GenericDeneme
{
class myclass // Normal Sınıf
{
}
{
class myclass // Normal Sınıf
{
}
class mygenclass1<tip1> // Generic Sınıf
{
}
{
}
class mygenclass2<tip1,tip2,tip3> // Birden çok tipli generic sınıf
{
}
}
{
}
}
Generic sınıflarda 1 adet tip tanımlana bileceği gibi yukarıdaki örneğimizde
mygenclass2 sınıfında da olduğu gibi ihtiyaçlar doğrultusunda birden çok tip
tanımlanabilir. Generic sınıfların tanımında bir aşırı yükleme (overloading)
gerçekleştirmek mümkün değildir. Generic sınıflardaki tanımlanmış tiplerdeki değişim
isimlerinin değiştiğini göstermez. Aşağıdaki örneği incelersek aynı isme fakat
farklı türde ve sayıda tiplere sahip sınıfların hata verdiğini göreceksiniz.
using System;
namespace GenericOverload
{
class mygenclass<tip1>{ } //
{
class mygenclass<tip1>{ } //
class mygenclass<tip1,tip2,tip3>{ } // Hata Çift Tanımlama
}
}
Generic sınıflarda normal sınıflarda olduğu gibi sınıf içinde sınıf tanımlamak
mümkündür. Bu tanımlamalar aşamasında dıştaki sınıfta kullanılan tip içteki sınıfta
da kullanılabilir. Burada dikkat edilmesi gereken konu içteki sınıfları
örneklerken dıştaki sınıfa ait generic tanımlamalar gerçekleştirilmelidir.
using System;
namespace GenericClass
{
class MyClass<ItemType>
{
public ItemType field1;
public void deneme(ItemType tmp){}
public MyClass(){}
public class MyClass2<ItemType>{}
}
class MainClass
{
[STAThread]
static void Main(string[] args)
{
MyClass<string> myclass = new MyClass<string>();
MyClass<int>.MyClass2<int> myclass2 = new MyClass<int>.MyClass2<int>();
}
}
}
namespace GenericClass
{
class MyClass<ItemType>
{
public ItemType field1;
public void deneme(ItemType tmp){}
public MyClass(){}
public class MyClass2<ItemType>{}
}
class MainClass
{
[STAThread]
static void Main(string[] args)
{
MyClass<string> myclass = new MyClass<string>();
MyClass<int>.MyClass2<int> myclass2 = new MyClass<int>.MyClass2<int>();
}
}
}
Generic Sınıflarda Türeme:
Generic sınıflarda türeme konusunda dikkat edilmesi
gereken en önemli nokta bir generic sınıfı türetmiş olduğumuz sınıfın veya
arayüzün adı ile generic sınıfımızda kullanmış olduğumuz parametre aynı isimde
olamaz. class Extend<V>: V {} şeklindeki
bir tanımlama hataya neden olacaktır. Bununla birlikte generic sınıfımızın başka
bir generic sınıftan türetilmesi durumunda temel sınıfımızda veya arayüzümüzde
aynı parametreyi kullanmak bir hataya sebep olmamaktadır. Aşağıda değişik şekillerde
türetilmiş generic sınıflar bulunmaktadır.
class C<U,V> {}
interface I1<V> {}
class D: C<string,int>, I1<string> {}
class E<T>: C<int,T>, I1<T> {}
Generic Sınıflarda Methodlar:
Generic sınıflarda kullanılan metotlar 2 şekilde incelenebilir. Bunlar Generic
Metotlar ve Generic Olmayan Metotlar. Peki bir metodun generic veya
non-generic olması arasındaki değişiklik nedir. Bir metodun içerisinde sınıf başlığında
tanımlanmış generic tiplerin kullanılması bu metodun generic bir metod olduğunu
göstermez. Şimdi aşağıdaki örneğimizi inceleyelim.
using System;
namespace GenericClass
{
class MyClass<ItemType1,ItemType2>
{
public ItemType1 field1;
public MyClass(){}
public void deneme(ItemType1 tmp){}
}
..................
..................
}
namespace GenericClass
{
class MyClass<ItemType1,ItemType2>
{
public ItemType1 field1;
public MyClass(){}
public void deneme(ItemType1 tmp){}
}
..................
..................
}
Yukarıda ki örneğimizde
sınıfta tanımlanmış olan generic tipler deneme metodu içerisinde kullanılmıştır.
Bu metot generic sınıfta tanımlanmış ama generic olmayan bir metottur.
Generic metodlar
metot adından sonra parametrelerden önce kullanılacak olan generic tiplerin tanımlanmasından
oluşur. Bu tanımlanan tipler sınıfta tanımlanan generic tiplerle aynı ada sahip
olabileceği gibi başka bir isimle de bulunabilirler. Aşağıda generic bir
metodun tanımlanması ve daha sonra kullanımını gösteren bir örnek bulunmaktadır.
using System;
namespace GenericClass
{
class MyClass<ItemType1,ItemType2>
{
public ItemType1 field1;
public MyClass(){}
public void deneme<ItemType3,ItemType1>()
{
ItemType3 myfiled;
Console.WriteLine(myfield.ToString());
}
}
class MainClass
{
namespace GenericClass
{
class MyClass<ItemType1,ItemType2>
{
public ItemType1 field1;
public MyClass(){}
public void deneme<ItemType3,ItemType1>()
{
ItemType3 myfiled;
Console.WriteLine(myfield.ToString());
}
}
class MainClass
{
MyClass C1 = new MyClass<int,string>();
C1.deneme<double>();
}
}
C1.deneme<double>();
}
}
Generic Metotlarda kullanılan Generic tipler içinde bulunduğu Generic sınıfa
ait tiplerle aynı isimde olabilir. Yukarıdaki örneğimizde Deneme metodumuzda
kullanılan ItemType1 MyClass üzerinde de kullanılmıştır.
Generic sınıflarda static alan ve metot kullanımında hiç bir farklılık
bulunmamaktadır. Static alan tanımlanırken sınıf üzerinde tanımlanmış olan
Generic tiplerde tür olarak kullanılabilir.
Microsoft Firmasının Whidbey’nin piyasaya sürülmesi ile ilgili planlarını
ileriye ötelemesi nedeniyle C#2.0 üzerinde bulunan generic sınıflarla ilgili
konuya detaylı bir yazı yazmaktan kaçındım. İlerleyen zamanlarda generic kavramı
daha detaylı olarak ta işlenecektir.
Hiç yorum yok:
Yorum Gönder