Aracılığıyla paylaş


Paketlenmiş Değere İzleme İşleyicisi

Değer türüne başvuru için izleme işleyicisi kullanımı C++ için Yönetilen Uzantılardan Visual C++ 2010'e değişmiştir.

Kutulama CLR birleştirilmiş tür sisteminin özelliğidir. Başvuru türleri örtülü bir çiftken, değer türleri durumlarını doğrudan içerir: adlandırılmış girdi yönetilmiş yığında ayrılmış bir adlandırılmamış nesneye bir işleyicidir. Örneğin, değer türünün bir Object'e herhangi bir başlatılması veya atanması, önce ilgili belleğin ayrılarak sonra değer türünün durumu kopyalanarak ve son olarak da bu anonim Değer/Başvuru karmasının adresi dönülerek değer türünün CLR yığınına yerleştirilmesini gerektirir. Bu sebeple, biri C#'ta yazdığında

object o = 1024; // C# implicit boxing

kodun basitliğinden göründüğünden çok daha fazla şey olur. C# tasarımı, sadece arka planda yer alan işlemlerin karmaşıklığını saklamakla kalmaz ayrıca kutulamanın kendi soyutlamasınında karmaşıklığını saklar. Diğer taraftan C++ için Yönetilen Uzantılar bunun yanlış verim düşüncesine yol açacağını düşünür, bunu açık yönerge gerektirerek kullanıcının önüne koyar:

Object *o = __box( 1024 ); // Managed Extensions explicit boxing

Visual C++ 2010'da kutulama dolaylıdır:

Object ^o = 1024; // new syntax implicit boxing

__box anahtar sözcüğü, Yönetilen Uzantılar içinde, C# ve Visual Basic gibi dillerde varsayılan olarak bulunmayan çok önemli bir hizmet sunar: hem bir sözlük hem de yönetilen yığında bir kutulu örneği doğrudan işlemek için bir izleme işleyicisi sağlar. Örneğin, aşağıdaki küçük programı düşünün:

int main() {
   double result = 3.14159;
   __box double * br = __box( result );

   result = 2.7; 
   *br = 2.17;   
   Object * o = br;

   Console::WriteLine( S"result :: {0}", result.ToString() ) ;
   Console::WriteLine( S"result :: {0}", __box(result) ) ;
   Console::WriteLine( S"result :: {0}", br );
}

Üç WriteLine çağrısı için üretilen arka plandaki kod kutulanmış değer türünün değerine erişimin çeşitli maliyetlerini, gösterilen satırlar her çağırmayla ilgili ek yükü gösterecek şekilde gösterir (bu farklılıkları belirttiği için Yves Dolce'ye teşekkürler).

// Console::WriteLine( S"result :: {0}", result.ToString() ) ;
ldstr      "result :: {0}"
ldloca.s   result  // ToString overhead
call       instance string  [mscorlib]System.Double::ToString()  // ToString overhead
call       void [mscorlib]System.Console::WriteLine(string, object)

// Console::WriteLine( S"result :: {0}", __box(result) ) ;
Ldstr    " result :: {0}"
ldloc.0
box    [mscorlib]System.Double // box overhead
call    void [mscorlib]System.Console::WriteLine(string, object)


// Console::WriteLine( S"result :: {0}", br );
ldstr    "result :: {0}"
ldloc.0
call     void [mscorlib]System.Console::WriteLine(string, object)

Kutulanmış değer türünü doğrudan Console::WriteLine'a geçirmek kutulamayı ve ToString() çağrısına ihtiyacı önler. Tabiki br'yi başlatmak için daha önce bir kutulama vardır bu sebeple br'yi gerçekten kullanıma koymadıkça bir şey kazanmayız.

Yeni sözdiziminde, kutulanmış değer türü desteği gücünü korurken çok daha zarif ve tür sistemiyle tümleşiktir. Örneğin, daha önceki küçük programın çevrilmiş hali aşağıdadır:

int main()
{
   double result = 3.14159;
   double^ br = result;
   result = 2.7;
   *br = 2.17;
   Object^ o = br;
   Console::WriteLine( "result :: {0}", result.ToString() );
   Console::WriteLine( "result :: {0}", result );
   Console::WriteLine( "result :: {0}", br );
}

Ayrıca bkz.

Görevler

How to: Explicitly Request Boxing

Kavramlar

Değer Türleri ve Davranışları