Genel Sınıflar (C# Programlama Kılavuzu)

Genel sınıflar, belirli bir veri türüne özgü olmayan işlemleri kapsüller. Genel sınıflar için en yaygın kullanım, bağlantılı listeler, karma tablolar, yığınlar, kuyruklar, ağaçlar vb. gibi koleksiyonlarla kullanılır. Koleksiyondan öğe ekleme ve kaldırma gibi işlemler, depolanmakta olan veri türüne bakılmaksızın temel olarak aynı şekilde gerçekleştirilir.

Koleksiyon sınıfları gerektiren çoğu senaryoda, önerilen yaklaşım .NET sınıf kitaplığında sağlananları kullanmaktır. Bu sınıfları kullanma hakkında daha fazla bilgi için bkz . .NET'te Genel Koleksiyonlar.

Genel olarak, mevcut somut bir sınıfla başlayıp genelleştirme ve kullanılabilirlik için en uygun dengeye ulaşana kadar türleri birer birer tür parametrelerine dönüştürerek genel sınıflar oluşturursunuz. Kendi genel sınıflarınızı oluştururken dikkat edilmesi gereken önemli noktalar şunlardır:

  • Tür parametrelerine genelleştirebileceğiniz türler.

    Kural olarak, ne kadar çok tür parametreleştirebilirseniz kodunuz o kadar esnek ve yeniden kullanılabilir hale gelir. Ancak çok fazla genelleştirme, diğer geliştiricilerin okuması veya anlaması zor olan kodlar oluşturabilir.

  • Varsa tür parametrelerine uygulanacak kısıtlamalar (Bkz. Tür Parametrelerindeki Kısıtlamalar).

    İyi bir kural, işlemeniz gereken türleri işlemenize izin verecek mümkün olan en yüksek kısıtlamaları uygulamaktır. Örneğin, genel sınıfınızın yalnızca başvuru türleriyle kullanılmak üzere tasarlandığını biliyorsanız, sınıf kısıtlamasını uygulayın. Bu, sınıfınızın değer türleriyle istenmeyen kullanımını engeller ve üzerinde Tişlecini as kullanmanıza ve null değerleri denetlemenize olanak tanır.

  • Genel davranışın temel sınıflara ve alt sınıflara dahil edilip edilmeyeceği.

    Genel sınıflar temel sınıflar olarak hizmet ettiğinden, burada genel olmayan sınıflarla aynı tasarım konuları geçerlidir. Bu konunun devamında yer alan genel temel sınıflardan devralma ile ilgili kurallara bakın.

  • Bir veya daha fazla genel arabirim uygulanıp uygulanmayacağı.

    Örneğin, generics tabanlı bir koleksiyonda öğe oluşturmak için kullanılacak bir sınıf tasarlarsanız, sınıfınızın türü nerede T gibi IComparable<T> bir arabirim uygulamanız gerekebilir.

Basit bir genel sınıf örneği için bkz . Genel Türlere Giriş.

Tür parametrelerinin ve kısıtlamalarının kurallarının, özellikle devralma ve üye erişilebilirliği ile ilgili genel sınıf davranışı üzerinde çeşitli etkileri vardır. Devam etmeden önce bazı terimleri anlamanız gerekir. Genel sınıf Node<T>, istemci kodu için, bir tür bağımsız değişkeni belirterek sınıfa başvurabilir - kapalı bir oluşturulmuş tür (Node<int>) oluşturmak için) veya tür parametresini belirtilmemiş bırakarak (örneğin, genel bir temel sınıf belirttiğinizde, açık oluşturulmuş bir tür (Node<T> ) oluşturmak için). Genel sınıflar somut, kapalı veya açık yapılı temel sınıflardan devralabilir:

class BaseNode { }
class BaseNodeGeneric<T> { }

// concrete type
class NodeConcrete<T> : BaseNode { }

//closed constructed type
class NodeClosed<T> : BaseNodeGeneric<int> { }

//open constructed type
class NodeOpen<T> : BaseNodeGeneric<T> { }

Genel olmayan, diğer bir deyişle, somut sınıflar kapalı oluşturulmuş temel sınıflardan devralabilir, ancak açık oluşturulmuş sınıflardan veya tür parametrelerinden devralabilir, çünkü istemci kodunun temel sınıfın örneğini oluşturmak için gereken tür bağımsız değişkenini sağlamasının çalışma zamanında hiçbir yolu yoktur.

//No error
class Node1 : BaseNodeGeneric<int> { }

//Generates an error
//class Node2 : BaseNodeGeneric<T> {}

//Generates an error
//class Node3 : T {}

Açık oluşturulmuş türlerden devralan genel sınıfların, aşağıdaki kodda gösterildiği gibi devralan sınıf tarafından paylaşılmayan temel sınıf türü parametreleri için tür bağımsız değişkenleri sağlaması gerekir:

class BaseNodeMultiple<T, U> { }

//No error
class Node4<T> : BaseNodeMultiple<T, int> { }

//No error
class Node5<T, U> : BaseNodeMultiple<T, U> { }

//Generates an error
//class Node6<T> : BaseNodeMultiple<T, U> {}

Açık oluşturulmuş türlerden devralan genel sınıflar, temel türdeki kısıtlamaların üst kümesi veya başka bir ifadeyle kısıtlamaları belirtmelidir:

class NodeItem<T> where T : System.IComparable<T>, new() { }
class SpecialNodeItem<T> : NodeItem<T> where T : System.IComparable<T>, new() { }

Genel türler, aşağıdaki gibi birden çok tür parametresi ve kısıtlaması kullanabilir:

class SuperKeyType<K, V, U>
    where U : System.IComparable<U>
    where V : new()
{ }

Açık oluşturulan ve kapalı oluşturulan türler yöntem parametreleri olarak kullanılabilir:

void Swap<T>(List<T> list1, List<T> list2)
{
    //code to swap items
}

void Swap(List<int> list1, List<int> list2)
{
    //code to swap items
}

Genel bir sınıf bir arabirim uygularsa, bu sınıfın tüm örnekleri bu arabirime yayınlanabilir.

Genel sınıflar sabit. Başka bir deyişle, bir giriş parametresi bir List<BaseClass>belirtirse, bir sağlamaya List<DerivedClass>çalışırsanız derleme zamanı hatası alırsınız.

Ayrıca bkz.