1 Ekim 2017 Pazar

Generics ve Wildcard

Upper Bound Generics
C#'ta generics ile kullanılan tiplere kısıt getirilebiliyor. Bu kısıtlar şöyle
  • where T : class (a) //constraint
  • where T : struct (b) //constraint
  • where T : new () (c) //constraint
  • where T : base class name (1) //ata
  • where T : interface name (2) //ata
  • where T : U (3) //ata
base class name (1), interface name (2) ve U (3) olanlar ata sınıf olarak kullanılabilir. Ayrıca base class name (1), interface name (2) ve U (3) class (a), struct (b) ,new (c) , olarak işaretlediğim kısıtlarla beraber de kullanılabilir. Ancak class (a) , struct (b) beraber kullanılamaz.
void DoSomething<T>() where T : class, struct //wont compile!
{    
   //...   
} 
struct
Açıklaması şöyle
The type argument must be a value type. Any value type except Nullable can be specified
Primary Constraint Önce Tanımlanmalıdır
class (a) veya struct (b) kısıtları base class name (1), interface name (2) ve U (3) tanımlarından önce gelmelidir. Yani şu kod derlenmez
public class Service<T> where T : IService, class
struct için şöyle yaparız
where T : struct
Constructor Constraint En Son Tanımlanmalıdır
new (c) en son tanımlanmalıdır.Şöyle yaparız.
protected T Clone<T>() where T : class, ICopyable<T>, new()
Ata Sınıf
Bu yöntem özellike kalıtım kullanan sınıflarda işe yarar. Bir diğer çözüm ise metod imzasını Covariant hale getirmek ancak bu işlem daha başka zorluklara sebep olabiliyor.

Örnek
Elimizde şöyle bir hiyerarşi olsun
abstract class Foo {}
class Bar : Foo {}
Foo tipinden liste alan bir metod olsun
void AddEntries(List<Foo>) {}
Bu metoda Bar tipinden bir liste geçmek istersek
List<Bar> barList = new List<Bar>()
AddEntries(barList);
Şu hatayı alırız.
cannot convert from List<Bar> to List<Foo>
Şöyle yapmak gerekir.
void AddEntries<T>(List<T> test) where T : Foo
{
    //your logic 
}
Örnek
Şöyle yaparız
class C<T> where T : Mammal {} // legal
Interface
Hem upper bound hem de kısıt kullanmak için şöyle yaparız.
class MyGenericClass<T> where T : class, IYourCommonInterface
{
    public void do()
    {
    }
}
Nested Class
Ata sınıfın generic tipine erişebilir. Şöyle yaparız.
public class A<T>
{
  public class B : A<int>
  {
    public void M() { System.Console.WriteLine(typeof(T)); }
    public class C : B { }
  }
}



Hiç yorum yok:

Yorum Gönder