C# Generic Tiplere Where İle Kısıtlama Getirmek - Constraints on Type Parameters

26.05.2017 Hikmet Okumuş 2870 2 C#


Merhaba arkadaşlar,

Generic bir tipe istenilen türde bir değer ataması yapabiliriz. Örneğin "System.Collections.Generic.List" sınıfı için bir generic tip ataması yapmak istediğimizde T yerine istediğimiz bir değeri atayabiliriz. Bunu bize sağlayan yapı List sınıfında herhangi bir generic type kısıtının olmamasından kaynaklanmaktadır.
Peki tüm tip değelerine açık bir atama olmasının dışında belirli bir kurala / kurallara göre atama yapılabilir duruma getirmek için ne yapmam lazım ? Bu noktada generic type kısıtlaması devreye girmektedir. Altı adet kısıtlama türü mevcuttur. Dilerseniz aşağıdaki linkten Microsoft' un ilgili dokümanını inceleyebilirsiniz. Benimde anlatacak olduğum konu başlıkları buradaki bilgileri kapsamaktadır.

Constraints on Type Parameters (C# Programming Guide)

Not: Generic sınıf tanımında bir kısıt belirttiğimizde ve ilgili generic nesneye tip atamasında kısıtlama dışında bir tip atandığında derleme zamanı hatası ile karşılaşırız.

where T: struct

Type argümanı bir değer türü olmalıdır.

class GenericList< T> where T : struct
{

}

static void Main(string[] args)
{
	GenericList< DateTime> s1 = new GenericList< DateTime>();		
}

where T : class

Type argümanı bir referans türü olmalıdır. Herhangi bir sınıf, arayüz, temsilci olabilir.

class Product
{

}

class GenericList< T> where T : class
{

}

static void Main(string[] args)
{
	GenericList< Product> s1 = new GenericList< Product>();
	GenericList< String> s2 = new GenericList< string>();
	//GenericList< DateTime> s3 = new GenericList< DateTime>();	
}

Yukarıda açıklama satırı olarak kapatılan kısım, üst tarafta açıklamasını yaptığımız derleme zamanı hatasını vermektedir. Çünkü "DateTime" bir değer türüne (struct) sahip nesnedir. Bizim GenericList sınıfımız için kısıtımız ise generic tip atamasının bir referans tipe ait olması şartını sağlamasıdır. Bu şartı sağlamadığı için derleyici aşağıdaki gibi bir hata vermektedir. Bu hata gibi diğer kısıt tiplerine göre uyumsuz olarak yapılan atamalar içinde benzer şekilde derleme zamanı hataları ile karşılaşırız.

www.hikmetokumus.com

where T : new()

Type argümanı parametre içermeyen bir yapıcı metoda sahip olmalıdır. Diğer kısıtlamalarla birlikte kullanıldığında, new () kısıtı en sonda belirtilmelidir.

    class Product
    {

    }    
    
    class GenericList< T> where T : class, new()
    {

    }
    
    static void Main(string[] args)
    {
        GenericList< Product> s1 = new GenericList< Product>();                       
    }    

Product sınıfını aşağıdaki gibi değiştirirsek derleme zamanı hatası alırız.

    class Product
    {
        public Product(string name)
        {

        }
    }

Kısıtımız bizden parametreye sahip olmayan bir yapıcı metod istemektedir. Aşağıdaki gibi bir düzeltme hatayı giderecektir.

    class Product
    {
        public Product() { }

        public Product(string name)
        {

        }
    }

where T : < base class name>

Type argümanı belirtilen taban sınıfından olmalı ya da türetilmelidir.

    class EntityBase
    {

    }

    class Entity : EntityBase
    {

    }

    class Product : Entity
    {
            
    }

    class GenericList< T> where T : EntityBase
    {

    }
    
    static void Main(string[] args)
    {
        GenericList< EntityBase> s1 = new GenericList< EntityBase>();
        GenericList< Entity> s2 = new GenericList< Entity>();
        GenericList< Product> s3 = new GenericList< Product>();
    }

where T : < interface name>

Type argümanı belirtilen arayüz olmalıdır ya da belirtilen arayüzü uygulamanız gerekir. Birden fazla arayüz kısıtlamaları belirtilebilir.

    interface IEntity
    {

    }

    class Product : IEntity
    {

    }

    class GenericList< T> where T : IEntity
    {

    }
    
    static void Main(string[] args)
    {
        GenericList< IEntity> s1 = new GenericList< IEntity>();
        GenericList< Product> s2 = new GenericList< Product>();
    }    

where T : U

T için verilen tür, U için verilen türden türemiş olması gerekmektedir.

    interface IEntity
    {

    }

    class Product : IEntity
    {

    }

    class GenericList< T, U> where T : U
    {

    }
    
    static void Main(string[] args)
    {
        GenericList< Product, IEntity> s1 = new GenericList< Product, IEntity>();
    }    

Çoklu Kısıtlama Parametreleri

Örneklerimizde tek bir where kısıtı kullandık. Ama bunu birden fazla yazmak mümkündür. Dilerseniz aşağıdaki gibi kullanabilirsiniz.

	class Base { }
	class Test< T, U>
	    where U : struct
	    where T : Base, new()

Başarılar dilerim.


Kullanıcı Yorumları


hikmet okumuş makale yorum
Sevtap
17.11.2017 17:37:07

Güzel bir makale olmuş

hikmet okumuş makale yorum
00reals00
29.01.2019 16:30:10

Öz bir makele olmuş. Ellerinize sağlık.



Yorum