Published on

C# Generic Yapılar Nedir ? Generic Metotlar, Class'lar Interface'ler Nasıl kullanılır ?

Authors
  • avatar
    Name
    Alperen Önal
    Twitter

Generic'ler ;

  • Önceden belirlenmiş veri tipi yerine, farklı veri tiplerinde çalışabilen kod yapıları oluşturmamıza olanak tanır.

  • Veri tiplerini önceden belirlemek yerine derleme zamanında (başka bir deyişle nesne oluşturduğumuz zaman) belirlenmesini sağlayarak kodumuzun esnek, yeniden kullanılabilir ve tür güvenli hale getirir.

  • Class'larda, metotlarda, arayüzlerde sıklıkla kullanılmaktadır.

Örneğin : Herhangi bir türden veriyi class'a ileterek muhaafaza etmek ve ihtiyacımız olunca verdiğimiz bu veriyi bir metot ile geri döndürmek olsun.

Aşağıdaki kod bunu kabaca ve amele usulü yapabiliyor. Önceden tanımlanmış veri tipleri için bize çalışma imkanı sunuyor.

public class Program
{

    public static void Main(string[] args)
    {
        MyClass myClass = new MyClass("merhaba");
        Console.WriteLine(myClass.GetValueString());


    }


}


public class MyClass
{
    private readonly object _data;

    public MyClass(string value)
    {

        _data = value;

    }

    public string GetValueString()
    {
        return (string)_data;

    }



}


Ancak ben bu class'ın sadece string tutmasını istemiyorum. Onun yerine string, int, float vs. tutabilsin.Bunun için de bir kod yazalım.

Aşağıdaki kod bunu yapabiliyor.

Ancak aşağıda da görebileceğiniz gibi kullanabileceğimiz veri tiplerini önceden belirlememiz ve daha sonra bunlar için ayrı ayrı metotlar oluşturmamız gerekiyor. Bu da, hem SOLID'i ihlal ediyor hem de kullanılabilecek veri tipi özgürlüğünü kısıtlıyor.

public class Program
{



    public static void Main(string[] args)
    {
        MyClass myClass = new MyClass(22);
        Console.WriteLine(myClass.GetValueInt());


    }


}


public class MyClass
{
    private readonly object _data;

    public MyClass(string value)
    {

        _data = value;

    }
    public MyClass(int value)
    {

        _data = value;

    }
    public MyClass(float value)
    {

        _data = value;

    }

    public string GetValueString()
    {
        return (string)_data;

    }

    public int GetValueInt()
    {
        return (int)_data;

    }
    public float GetValuefloat()
    {
        return (float)_data;

    }


}


Bunun yerine tek bir metodumuz ve class'ımız olsun, çalışacağımız veri tiplerini önceden belirlemek yerine bu veri tipleri bizim isteğimiz doğrultusunda derleme zamanı belirlensin.

İşte bu durumda generic yapılarını kullanmak durumunda kalıyoruz.

Aşağıdaki kodda generic class ve generic method kullanılarak bu sorun çözülmüştür.

public class Program
{



    public static void Main(string[] args)
    {
        MyGenericClass<string> myGenericClass = new MyGenericClass<string>("Selamlar");
        Console.WriteLine(myGenericClass.GetValue().ToString());


    }


}


public class MyGenericClass<T>
{
    private readonly T _data;

    public MyGenericClass(T value)
    {

        _data = value;

    }

    public T GetValue()
    {
        return _data;

    }



}


Generic yapıların ne olduğunu ve neden kullanıldığını gördüğümüze göre şimdi de nasıl kullanıldıklarını görelim.

Generic yapıları tanımlamak için "<>" sembolünü kullanmaktayız. Genellikle "<>" içerisine "T" harfi yazılması tercih edilir(örn :"<T>") ama tabii ki istediğinizi yazabilirsiniz.

Generic Class Örnekleri


public class MyGenericClass<T>
{
    private readonly T _data; //T olarak tanımladığınız Generic tipini kullanarak bir field oluşturabilir ve kullanabilirsiniz.

    //diğer işlemler
}



// MyGenericClass<int> myGenericClass = new MyGenericClass<int>(15); denilmiş olsun.
// O halde, aşağıdaki _data1 ve _data2'nin veri tipleri aynı yani int olacaktır.

public class MyGenericClass<T>
{
    private readonly T _data1;
    private readonly T _data2;

    //diğer işlemler
}

// MyGenericClass<int, string> myGenericClass = new MyGenericClass<int, string>(15, "selam"); denilmiş olsun.
// O halde, aşağıdaki _data1 ve _data2'nin veri tipleri farklı olacaktır. Birisi int diğeri string olacaktır.

public class MyGenericClass<T1, T2>
{
    private readonly T1 _data1;
    private readonly T2 _data2;

    //diğer işlemler
}


Generic Metot Örnekleri

public class Program
{
    public static void Main(string[] args)
    {
        OrnekClass ornekClass = new OrnekClass();
        ornekClass.Yazdir("selam");
        ornekClass.Yazdir(5);

    }


}


public class OrnekClass
{

    public void Yazdir<T>(T value)
    {
        Console.WriteLine(value);

    }

    //diğer işlemler
}



public class Program
{
    public static void Main(string[] args)
    {
        OrnekClass ornekClass = new OrnekClass();
        Console.WriteLine(ornekClass.EsitMi(5, 2));
        Console.WriteLine(ornekClass.EsitMi("selam", "selam"));


    }


}


public class OrnekClass
{

    public bool EsitMi<T>(T value1, T value2)
    {
        return value1.Equals(value2);

    }

    //diğer işlemler
}


Çıktı :

False
True

Generic Interface Örnekleri

public interface IContainer<T>
{
    void Add(T item);
    T Get(int index);
}

İmplement edelim :

public class Container<T> : IContainer<T>
{
    private List<T> _items = new List<T>();

    public void Add(T item)
    {
        _items.Add(item);
    }

    public T Get(int index)
    {
        if (index < 0 || index >= _items.Count)
            throw new ArgumentOutOfRangeException(nameof(index));

        return _items[index];
    }
}

Umarım faydalı olmuştur. Yazımız bu kadardı.