31 Temmuz 2011 Pazar

C# Generic Kısıtlamalar

Generic tasarım yaparken bazı kısıtlamalar getirmemiz mümkündür. Bu kısıtlamaları 5 madde halinde inceleyeceğiz.

1) Referans Türlü Olmaya Zorlamak

Generic parametre yerine yazılacak tipin yalnızca referans türlü olması,

class Test<T> where T : class

    {

        void Deneme(T parametre)

        {

            /...

        }

    }

Burada “class” anahtar sözcüğü referans türlü herhangi bir tipi temsil etmektedir. Bu kısıtlama ile T yerine değer türlü bir tip yazamayız.

2) Değer Türlü Olmaya Zorlamak

Generic parametre yerine yazılacak tipin yalnızca değer türlü olması,

class Test<T> where T : struct

    {

        void Deneme(T parametre)

        {

            //...

        }

    }

3) Belli bir tipten kalıtılmaya zorlamak

class Personel

    {

        public int Id { get; set; }

        public string Ad { get; set; }

    }

 

    class Mudur : Personel

    {

        public string Departman { get; set; }

    }

 

    class Test<T> where T : Personel

    {

        void Deneme(T parametre)

        {

            Console.WriteLine(parametre.Id);

            Console.WriteLine(parametre.Ad);

        }

    }

T parametresi yerine Personel veya Personelden kalıtılmış herhangi bir tip yazabiliriz. Bu örnek için konuşacak olursak T yerine Mudur de yazabiliriz, çünkü Mudur de bir Personel’dir.

4) Belli bir Interface’I implement etmeye zorlamak

class Test<T> where T : IEnumerable

    {

        void Deneme(T parametre)

        {

            foreach(object obj in parametre)

                Console.WriteLine(obj);

        }

    }

IEnumerable interface’I foreach ile gezdiren nesnedir. Dolayısıyla burada T’nin IEnumerable interface’ini implement edeceğini belirtmeseydik hata alacaktık. Çünkü deneme metodunun içinde, parametre adlı değişkenin içerisinde foreach geziyoruz. Tasarım anında derleyici bu değişkenin içerisinde foreach ile gezilip gezilemeyeceğini bilemez. Biz IEnumerable kısıtlaması getirerek T’nin, içerisinde foreach ile gezilebilecek bir nesne olduğunu vurgulamış olduk.

5) Default, yani parametresiz yapıcı metot bulundurmaya zorlamak

class Test<T> where T : new()

    {

        void Deneme()

        {

            T obj = new T();

        }

    }

Burada T yerine gelecek tipin, parametresiz constructor’a sahip olma zorunluluğunu sağladık. Yani T tipi, nesnesi örneklenebilir bir tip olmak zorundadır. Bu cümleye dayanarak yorum yaparsak,

-T tipi abstract olamaz.

-T tipinin parametresiz, yani varsayılan constrcutor’u olmak zorundadır.

-Bu kısıtlamaları bir arada kullanabilmemiz de mümkündür.

class Test<T> where T : class,IDisposable, new()

    {

        //..

    }

 

   

class Test2<T, K, L>

        where K : IComparable

        where L : IComparable

        where T : struct,IEnumerable

    {

        void Deneme(K parametre1, L parametre2)

        {

            //..

        }

 

    }