Um identificador de acompanhamento para um valor in a box

O uso de uma alça de acompanhamento para um tipo de valor de referência foi alterado de gerenciado Extensions para C++ para Visual C++ 2008.

Conversão boxing é uma particularidade do sistema de tipos do CLR unificado.Tipos de valor contêm diretamente seu estado, enquanto os tipos de referência são um emparelhar implícito: a entidade nomeada é um identificador para um objeto sem nome alocado no heap gerenciado.Qualquer inicialização ou a atribuição de um tipo de valor para um Object, por exemplo, requer que o tipo de valor sejam colocados dentro do heap CLR – isso é onde surge a imagem de conversão boxing ele – primeiro por alocar a memória associada, depois, copiando estado do tipo de valor e, em seguida, retornando o endereço desse anônimo híbrido de valor/referência. Assim, quando um grava no translation from VPE for Csharp

object o = 1024; // C# implicit boxing

Há muito mais acontecendo que é feita aparente a simplicidade do código.O design de translation from VPE for Csharp oculta a complexidade não apenas de quais operações estão acontecendo nos bastidores, mas também de abstração de conversão boxing propriamente dito.gerenciado Extensions para C++, por Outros lado, preocupados que isso levaria a uma falsa sensação de eficiência, coloca na face do usuário, exigindo uma instrução explícita:

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

Conversão boxing é implícita no Visual C++ 2008:

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

The __box palavra-chave serve a um serviço vital na extensões gerenciadas, um que esteja faltando pelo design de idiomas such sistema autônomo translation from VPE for Csharp e Visual Basic: Ele fornece um vocabulário e acompanhamento de identificador para manipular diretamente uma instância in a box no heap gerenciado.Por exemplo, considere o seguinte programa pequeno:

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 );
}

O código subjacente gerado para as três chamadas de WriteLine Mostre os vários custos de acessando o valor de um tipo de valor convertidos (graças à Yves Dolce para indicar essas diferenças), onde as linhas indicadas mostram a sobrecarga associada a cada chamada.

// 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)

Passando o tipo de valor convertidos diretamente para Console::WriteLine elimina a conversão boxing e a necessidade de chamar ToString(). (Naturalmente, há a conversão boxing anterior ao inicializar br, portanto, não obtemos nada, a menos que colocamos realmente br para trabalhar.

A nova sintaxe, o suporte para tipos de valor convertidos é consideravelmente mais elegante e integrado no sistema de tipo, mantendo sua capacidade.Por exemplo, aqui está a tradução do programa pequeno anterior:

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 );
}

Consulte também

Tarefas

Como: Solicitar explicitamente Boxing

Conceitos

Tipos de valor e seus comportamentos