Aşağıda aşağıdaki makaleden bir gönderi var :
Zorlama ve oyuncu seçimi arasındaki fark genellikle ihmal edilir. Nedenini anlayabiliyorum; birçok dil her iki işlem için de aynı (veya benzer) sözdizimine ve terminolojiye sahiptir. Hatta bazı diller herhangi bir dönüşüme "döküm" olarak atıfta bulunabilir, ancak aşağıdaki açıklama CTS'deki kavramlara atıfta bulunmaktadır.
Farklı türde bir konuma bir türden bir değer atamaya çalışıyorsanız, yeni türün orijinaline benzer anlamı olan bir değer üretebilirsiniz. Bu zorlamadır. Zorlama, bir şekilde orijinaline benzeyen yeni bir değer oluşturarak yeni türü kullanmanıza izin verir. Bazı zorlamalar verileri atabilir (örneğin, int 0x12345678'i kısa 0x5678'e dönüştürme), bazıları ise vermeyebilir (örneğin int 0x00000008'i kısa 0x0008'e veya uzun 0x0000000000000008'e dönüştürme).
Değerlerin birden çok türe sahip olabileceğini hatırlayın. Durumunuz biraz farklıysa ve değer türlerinden yalnızca farklı birini seçmek istiyorsanız, döküm işin aracıdır. Çevrim, bir değerin içerdiği belirli bir tür üzerinde işlem yapmak istediğinizi belirtir.
Kod seviyesindeki fark C # ile IL arasında değişir. C #'da hem döküm hem de zorlama oldukça benzer görünür:
static void ChangeTypes(int number, System.IO.Stream stream)
{
long longNumber = number;
short shortNumber = (short)number;
IDisposable disposableStream = stream;
System.IO.FileStream fileStream = (System.IO.FileStream)stream;
}
IL düzeyinde oldukça farklıdırlar:
ldarg.0
conv.i8
stloc.0
ldarg.0
conv.i2
stloc.1
ldarg.1
stloc.2
ldarg.1
castclass [mscorlib]System.IO.FileStream
stloc.3
Mantıksal seviyeye gelince, bazı önemli farklılıklar vardır. Hatırlanması gereken en önemli şey, zorlamanın yeni bir değer yaratmasıdır, ancak döküm yapmaz. Orijinal değerin kimliği ve dökümden sonraki değer aynı iken, zorlanmış bir değerin kimliği orijinal değerden farklıdır; dönüştürme yeni, farklı bir örnek oluşturur, ancak döküm yapmaz. Bunun bir doğal sonucu, dökümün sonucunun ve orijinalin her zaman eşdeğer olacağı (hem özdeşlik hem de eşitlik açısından), ancak zorunlu bir değer orijinaline eşit olabilir veya olmayabilir ve asla orijinal kimliği paylaşmaz.
Sayısal türler her zaman değere göre kopyalandığından, yukarıdaki örneklerde zorlamanın sonuçlarını görmek kolaydır. Referans türleriyle çalışırken işler biraz daha karmaşık hale gelir.
class Name : Tuple<string, string>
{
public Name(string first, string last)
: base(first, last)
{
}
public static implicit operator string[](Name name)
{
return new string[] { name.Item1, name.Item2 };
}
}
Aşağıdaki örnekte, bir dönüştürme, diğeri bir zorlamadır.
Tuple<string, string> tuple = name;
string[] strings = name;
Bu dönüşümlerden sonra tuple ve name eşittir, ancak dizeler ikisine de eşit değildir. Bir Name ile bir dizeyi [] karşılaştırmak için Name sınıfına Equals () ve operator == () uygulayarak durumu biraz daha iyi (veya biraz daha kafa karıştırıcı) yapabilirsiniz. Bu operatörler karşılaştırma sorununu "düzeltir", ancak yine de iki ayrı örneğiniz olur; Dizelerde yapılan herhangi bir değişiklik ad veya dizide yansıtılmazken, ad veya demetten birinde yapılan değişiklikler ad ve tuple'a yansıtılır, ancak dizelerde yansıtılmaz.
Yukarıdaki örnek, döküm ve zorlama arasındaki bazı farklılıkları göstermeyi amaçlasa da, C # 'da referans türleriyle dönüştürme operatörlerini kullanma konusunda neden son derece dikkatli olmanız gerektiğine dair harika bir örnek teşkil eder.