description | title | ms.date | ms.topic | helpviewer_keywords | ms.assetid | |
---|---|---|---|---|---|---|
Learn more about: Boxing (C++/CLI and C++/CX) | Boxing (C++/CLI and C++/CX) | 10/12/2018 | reference |
| b5fd2c98-c578-4f83-8257-6dd663478665 |
The conversion of value types to objects is called boxing, and the conversion of objects to value types is called unboxing.
(There are no remarks for this language feature that apply to all runtimes.)
C++/CX supports a shorthand syntax for boxing value types and unboxing reference types. A value type is boxed when it is assigned to a variable of type Object
. An Object
variable is unboxed when it is assigned to a value type variable and the unboxed type is specified in parentheses; that is, when the object variable is cast to a value type.
Platform::Object^ object_variable = value_variable; value_variable = (value_type) object_variable;
Compiler option: /ZW
The following code example boxes and unboxes a DateTime
value. First, the example obtains a DateTime
value that represents the current date and time and assigns it to a DateTime
variable. Then the DateTime
is boxed by assigning it to an Object
variable. Finally, the boxed value is unboxed by assigning it to another DateTime
variable.
To test the example, create a BlankApplication
project, replace the BlankPage::OnNavigatedTo()
method, and then specify breakpoints at the closing bracket and the assignment to variable str1
. When the example reaches the closing bracket, examine str1
.
voidBlankPage::OnNavigatedTo(NavigationEventArgs^ e) { usingnamespaceWindows::Globalization::DateTimeFormatting; Windows::Foundation::DateTime dt, dtAnother; Platform::Object^ obj1; Windows::Globalization::Calendar^ c = ref new Windows::Globalization::Calendar; c->SetToNow(); dt = c->GetDateTime(); auto dtf = ref newDateTimeFormatter( YearFormat::Full, MonthFormat::Numeric, DayFormat::Default, DayOfWeekFormat::None); String^ str1 = dtf->Format(dt); OutputDebugString(str1->Data()); OutputDebugString(L"\r\n"); // Box the value type and assign to a reference type. obj1 = dt; // Unbox the reference type and assign to a value type. dtAnother = (Windows::Foundation::DateTime) obj1; // Format the DateTime for display. String^ str2 = dtf->Format(dtAnother); OutputDebugString(str2->Data()); }
For more information, see Boxing (C++/CX).
The compiler boxes value types to xref:System.Object. This is possible because of a compiler-defined conversion to convert value types to xref:System.Object.
Boxing and unboxing enable value types to be treated as objects. Value types, including both struct types and built-in types such as int, can be converted to and from the type xref:System.Object.
For more information, see:
Compiler option: /clr
The following sample shows how implicit boxing works.
// vcmcppv2_explicit_boxing2.cpp// compile with: /clrusingnamespaceSystem; ref classA { public:voidfunc(System::Object^ o){Console::WriteLine("in A");} }; value classV {}; interface structIFace { voidfunc(); }; value classV1 : publicIFace { public:virtualvoidfunc() { Console::WriteLine("Interface function"); } }; value structV2 { // conversion operator to System::Objectstaticoperator System::Object^(V2 v2) { Console::WriteLine("operator System::Object^"); return (V2^)v2; } }; voidfunc1(System::Object^){Console::WriteLine("in void func1(System::Object^)");} voidfunc1(V2^){Console::WriteLine("in func1(V2^)");} voidfunc2(System::ValueType^){Console::WriteLine("in func2(System::ValueType^)");} voidfunc2(System::Object^){Console::WriteLine("in func2(System::Object^)");} intmain() { // example 1 simple implicit boxing Int32^ bi = 1; Console::WriteLine(bi); // example 2 calling a member with implicit boxing Int32 n = 10; Console::WriteLine("xx = {0}", n.ToString()); // example 3 implicit boxing for function calls A^ a = gcnew A; a->func(n); // example 4 implicit boxing for WriteLine function call V v; Console::WriteLine("Class {0} passed using implicit boxing", v); Console::WriteLine("Class {0} passed with forced boxing", (V^)(v)); // force boxing// example 5 casting to a base with implicit boxing V1 v1; IFace ^ iface = v1; iface->func(); // example 6 user-defined conversion preferred over implicit boxing for function-call parameter matching V2 v2; func1(v2); // user defined conversion from V2 to System::Object preferred over implicit boxing// Will call void func1(System::Object^);func2(v2); // OK: Calls "static V2::operator System::Object^(V2 v2)"func2((V2^)v2); // Using explicit boxing: calls func2(System::ValueType^) }
1 xx = 10 in A Class V passed using implicit boxing Class V passed with forced boxing Interface function in func1(V2^) in func2(System::ValueType^) in func2(System::ValueType^)