Uma alça de controle para um valor in a box
O uso de uma alça de controle para fazer referência a um tipo de valor foi alterado a partir de Managed Extensions for C++ para Visual C++ 2010.
Boxing é um peculiarity do sistema de tipo CLR unificado. Tipos de valor contêm diretamente o seu estado, enquanto os tipos de referência são um par de 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 valor de tipo um Object, por exemplo, requer que o tipo de valor ser colocado dentro do heap CLR – isso é onde surge a imagem de boxing ele – primeiro por alocar a memória associada, em seguida, copiando o estado do tipo de valor, e, em seguida, retornando o endereço deste híbrido de valor/referência anônimo. Assim, quando um grava no C#
object o = 1024; // C# implicit boxing
Há muito mais acontecendo que fica aparente pela simplicidade do código. O design de C# oculta a complexidade, não apenas as operações que estão acontecendo nos bastidores, mas também de que a abstração de boxing propriamente dito. Managed Extensions for C++, por outro lado, preocupado 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
Boxing está implícito em Visual C++ 2010:
Object ^o = 1024; // new syntax implicit boxing
O __box palavra-chave serve a um serviço vital dentro de Managed Extensions, que está ausente por design de linguagens como, por exemplo, C# e Visual Basic: Ele fornece um vocabulário e controlando a alça para manipular diretamente uma instância do processador 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 Mostrar os vários custos de acessar o valor de um tipo de valor convertidos (Meus agradecimentos a Yves Dolce para ressaltando a essas diferenças), onde a apresentação de linhas indicada a sobrecarga associada cada invocação.
// 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 de boxing e a necessidade de chamar ToString(). (Obviamente, há a conversão boxing anterior ao inicializar br, portanto, não obtemos nada, a menos que realmente colocamos br para o trabalho.
A nova sintaxe, o suporte para tipos de valor convertidos é consideravelmente mais elegante e integrado dentro do sistema de tipo, mantendo o seu poder. 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
How to: Explicitly Request Boxing