C++/CLI'da Genel Değerlere Genel Bakış
Genel türler, ortak dil çalışma zamanı tarafından desteklenen parametreli türlerdir. Parametreli tür, genel kullanıldığında belirtilen bilinmeyen tür parametresiyle tanımlanan bir türdür.
Neden Generics?
C++ şablonları destekler ve hem şablonlar hem de genel türler, türlenmiş koleksiyon sınıfları oluşturmak için parametreli türleri destekler. Ancak şablonlar derleme zamanı parametresini sağlar. Şablon tanımı içeren bir derlemeye başvuramaz ve şablonun yeni özelleştirmelerini oluşturamazsınız. Derlendiğinde, özelleştirilmiş bir şablon başka bir sınıf veya yöntem gibi görünür. Buna karşılık, genel değerler MSIL'de çalışma zamanı tarafından parametreli tür olarak bilinen parametreli bir tür olarak yayılır; genel tür içeren bir derlemeye başvuran kaynak kodu, genel türde özelleştirmeler oluşturabilir. Standart C++ şablonlarının ve genel türlerin karşılaştırması hakkında daha fazla bilgi için bkz . Genel Ve Şablonlar (C++/CLI).
Genel İşlevler ve Türler
Yönetilen türler olduğu sürece sınıf türleri genel olabilir. Bunun bir örneği bir List
sınıf olabilir. Listedeki bir nesnenin türü type parametresi olacaktır. Birçok farklı nesne türü için bir List
sınıfa ihtiyacınız varsa, genel öğelerden önce öğe türü olarak alan System::Object
bir List
kullanmış olabilirsiniz. Ancak bu, listede herhangi bir nesnenin (yanlış türdeki nesneler dahil) kullanılmasına izin verir. Böyle bir liste, yazılmamış koleksiyon sınıfı olarak adlandırılır. En iyi durumda, çalışma zamanında türü denetleyebilir ve bir özel durum oluşturabilirsiniz. Veya bir derlemede derlendiğinde genel kalitesini kaybedecek bir şablon kullanmış olabilirsiniz. Derlemenizin tüketicileri şablonun kendi uzmanlık alanlarını oluşturamadı. Genel değerler, türü List<int>
belirtilen koleksiyona kabul etmek üzere tasarlanmamış bir tür yerleştirmeye çalışırsanız derleme zamanı hatası oluşturacak olan ("Int listesi" ve List<double>
("Çiftin listesi") gibi türlenmiş koleksiyon sınıfları oluşturmanıza olanak sağlar. Ayrıca, bu türler derledikten sonra genel kalır.
Genel sınıfların söz diziminin açıklaması Genel Sınıflar (C++/CLI) içinde bulunabilir. yeni bir ad alanı olan System.Collections.Generic, ve LinkedList<T>gibi Dictionary<TKey,TValue>List<T> parametreli koleksiyon türleri kümesi sunar.
Hem örnek hem de statik sınıf üyesi işlevleri, temsilciler ve genel işlevler de genel olabilir. İşlevin parametreleri bilinmeyen türdeyse veya işlevin kendisinin genel türlerle çalışması gerekiyorsa genel işlevler gerekebilir. Geçmişte bilinmeyen bir nesne türü için parametre olarak kullanılmış olabilecek çoğu durumda System::Object
, bunun yerine genel tür parametresi kullanılabilir ve böylece daha fazla tür güvenli kod elde edilebilir. İşlevin tasarlanmadığı bir tür geçirme girişimi, derleme zamanında hata olarak işaretlenir. İşlev parametresi olarak kullanıldığında System::Object
, işlevin ilgilenmediği bir nesnenin yanlışlıkla geçirilmesi algılanmaz ve bilinmeyen nesne türünü işlev gövdesindeki belirli bir türe atamanız ve InvalidCastException olasılığını hesaba katmak zorunda olursunuz. Bir genel ile, işleve bir nesne geçirmeye çalışan kod bir tür çakışmasına neden olur, bu nedenle işlev gövdesinin doğru türe sahip olacağı garanti edilir.
Aynı avantajlar, genel değerler üzerinde oluşturulan koleksiyon sınıfları için de geçerlidir. Geçmişteki koleksiyon sınıfları, öğeleri bir koleksiyonda depolamak için kullanırdı System::Object
. Koleksiyonun tasarlanmadığı bir türdeki nesnelerin eklenmesi, derleme zamanında ve çoğunlukla nesneler eklendiğinde bile işaretlenmedi. Genellikle, bir nesne koleksiyonda erişildiğinde başka bir türe dönüştürülür. Yalnızca atama başarısız olduğunda beklenmeyen tür algılanabilir. Genel değerler, genel koleksiyonun tür parametresiyle eşleşmeyen (veya örtük olarak dönüştüren) bir tür ekleyen kodu algılayarak derleme zamanında bu sorunu çözer.
Söz diziminin açıklaması için bkz . Genel İşlevler (C++/CLI).
Genel Türlerle Kullanılan Terminoloji
Tür Parametreleri
Genel bildirim, tür parametreleri olarak bilinen bir veya daha fazla bilinmeyen tür içerir. Tür parametrelerine, genel bildirimin gövdesindeki türün kısaltması olan bir ad verilir. tür parametresi, genel bildirimin gövdesinde bir tür olarak kullanılır. için List<T>
genel bildirim, T tür parametresini içerir.
Tür Bağımsız Değişkenleri
Tür bağımsız değişkeni , genel belirli bir tür veya tür için özel olduğunda tür parametresi yerine kullanılan gerçek türdür. Örneğin, int
içindeki List<int>
tür bağımsız değişkenidir. Değer türleri ve tanıtıcı türleri, genel tür bağımsız değişkeni olarak yalnızca içinde izin verilen türlerdir.
Yapılı Tür
Genel bir türden yapılan bir tür, yapılı tür olarak adlandırılır. Açık bir tür gibi tam olarak List<T>
belirtilmemiş bir tür; gibi tam olarak List<double>
belirtilen bir tür, kapalı bir yapılı tür veya özel türdür. Açık yapılı türler, diğer genel türlerin veya yöntemlerin tanımında kullanılabilir ve kapsayan genel türün kendisi belirtilene kadar tam olarak belirtilmeyebilir. Örneğin, aşağıda genel bir için temel sınıf olarak açık oluşturulmuş bir türün kullanımı verilmiştir:
// generics_overview.cpp
// compile with: /clr /c
generic <typename T>
ref class List {};
generic <typename T>
ref class Queue : public List<T> {};
Kısıtlama
Kısıtlama, tür parametresi olarak kullanılabilecek türlerdeki bir kısıtlamadır. Örneğin, belirli bir genel sınıf yalnızca belirtilen bir sınıftan devralan sınıfları kabul edebilir veya belirtilen bir arabirimi uygulayabilir. Daha fazla bilgi için bkz . Genel Tür Parametrelerindeki Kısıtlamalar (C++/CLI).
Başvuru Türleri ve Değer Türleri
Türleri işler ve değer türleri tür bağımsız değişkenleri olarak kullanılabilir. Her iki türün de kullanılabildiği genel tanımda, söz dizimi başvuru türlerinin söz dizimidir. Örneğin işleç, ->
sonunda kullanılan türün bir başvuru türü veya değer türü olup olmadığına bakılmaksızın tür parametresi türünün üyelerine erişmek için kullanılır. Tür bağımsız değişkeni olarak bir değer türü kullanıldığında, çalışma zamanı değer türlerini kutulamadan doğrudan değer türlerini kullanan bir kod oluşturur.
Başvuru türünü genel tür bağımsız değişkeni olarak kullanırken tutamaç söz dizimini kullanın. Bir değer türünü genel tür bağımsız değişkeni olarak kullanırken, türün adını doğrudan kullanın.
// generics_overview_2.cpp
// compile with: /clr
generic <typename T>
ref class GenericType {};
ref class ReferenceType {};
value struct ValueType {};
int main() {
GenericType<ReferenceType^> x;
GenericType<ValueType> y;
}
Tür Parametreleri
Genel bir sınıftaki tür parametreleri diğer tanımlayıcılar gibi değerlendirilir. Ancak, türü bilinmediğinden, bunların kullanımıyla ilgili kısıtlamalar vardır. Örneğin, tür parametresinin bu üyeleri desteklediği bilinmediği sürece tür parametresi sınıfının üyelerini ve yöntemlerini kullanamazsınız. Başka bir ifadeyle, tür parametresi aracılığıyla bir üyeye erişmek için, üyeyi içeren türü tür parametresinin kısıtlama listesine eklemeniz gerekir.
// generics_overview_3.cpp
// compile with: /clr
interface class I {
void f1();
void f2();
};
ref struct R : public I {
virtual void f1() {}
virtual void f2() {}
virtual void f3() {}
};
generic <typename T>
where T : I
void f(T t) {
t->f1();
t->f2();
safe_cast<R^>(t)->f3();
}
int main() {
f(gcnew R());
}
Bu kısıtlamalar işleçler için de geçerlidir. Kısıtlanmamış bir genel tür parametresi, türün ==
bu işleçleri desteklememesi durumunda tür parametresinin iki örneğini karşılaştırmak için ve !=
işleçlerini kullanmayabilir. Bu denetimler genel öğeler için gereklidir, ancak şablonlar için gerekli değildir, çünkü genel öğeler, geçersiz üyelerin kullanımını denetlemek için çok geç olduğunda kısıtlamaları karşılayan herhangi bir sınıfla çalışma zamanında özelleştirilebilir.
tür parametresinin varsayılan örneği işleci kullanılarak ()
oluşturulabilir. Örneğin:
T t = T();
burada T
, genel bir sınıf veya yöntem tanımında tür parametresidir, değişkeni varsayılan değerine başlatır. Başvuru sınıfı ise T
null işaretçi olur; değer sınıfı ise T
nesne sıfır olarak başlatılır. Bu, varsayılan başlatıcı olarak adlandırılır.