Konwersja boxing (C++/CLI i C++/CX)

Konwersja typów wartości na obiekty jest nazywana boxingiem, a konwersja obiektów na typy wartości jest nazywana rozpętowywaniem.

Wszystkie środowiska wykonawcze

(Nie ma żadnych uwag dotyczących tej funkcji językowej, która ma zastosowanie do wszystkich środowisk uruchomieniowych).

Środowisko wykonawcze systemu Windows

Język C++/CX obsługuje skróconą składnię typów wartości boksu i typów odwołań rozpakowy. Typ wartości jest boxed, gdy jest przypisany do zmiennej typu Object. Zmienna Object jest rozpakowana, gdy jest przypisana do zmiennej typu wartości, a typ rozpakowany jest określony w nawiasach; oznacza to, że gdy zmienna obiektu jest rzutowana na typ wartości.

  Platform::Object^
  object_variable  = value_variable;
value_variable = (value_type) object_variable;

Wymagania

Opcja kompilatora: /ZW

Przykłady

Poniższe przykładowe pola kodu i rozpatłają DateTime wartość. Najpierw przykład uzyskuje wartość reprezentującą bieżącą DateTime datę i godzinę i przypisuje ją do zmiennej DateTime . DateTime Następnie element jest w polu, przypisując go do zmiennejObject. Na koniec pole wartość jest rozpaszczone, przypisując ją do innej DateTime zmiennej.

Aby przetestować przykład, utwórz projekt, zastąp metodę BlankApplication , a następnie określ punkty przerwania w nawiasie zamykającym i przypisanie do zmiennej str1.BlankPage::OnNavigatedTo() Gdy przykład osiągnie nawias zamykający, sprawdź str1wartość .

void BlankPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    using namespace Windows::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 new DateTimeFormatter(
                           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());
}

Aby uzyskać więcej informacji, zobacz Boxing (C++/CX).

środowiska uruchomieniowe w trakcie wykonania

Typy wartości pól kompilatora do Object. Jest to możliwe z powodu konwersji zdefiniowanej przez kompilator w celu konwersji typów wartości na Object.

Boxing i rozpakowywanie umożliwiają traktowanie typów wartości jako obiektów. Typy wartości, w tym typy struktur i wbudowane typy, takie jak int, można konwertować na i z typu Object.

Aby uzyskać więcej informacji, zobacz:

Wymagania

Opcja kompilatora: /clr

Przykłady

Poniższy przykład pokazuje, jak działa niejawne boksowanie.

// vcmcppv2_explicit_boxing2.cpp
// compile with: /clr
using namespace System;

ref class A {
public:
   void func(System::Object^ o){Console::WriteLine("in A");}
};

value class V {};

interface struct IFace {
   void func();
};

value class V1 : public IFace {
public:
   virtual void func() {
      Console::WriteLine("Interface function");
   }
};

value struct V2 {
   // conversion operator to System::Object
   static operator System::Object^(V2 v2) {
      Console::WriteLine("operator System::Object^");
      return (V2^)v2;
   }
};

void func1(System::Object^){Console::WriteLine("in void func1(System::Object^)");}
void func1(V2^){Console::WriteLine("in func1(V2^)");}

void func2(System::ValueType^){Console::WriteLine("in func2(System::ValueType^)");}
void func2(System::Object^){Console::WriteLine("in func2(System::Object^)");}

int main() {
   // 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^)

Zobacz też

Rozszerzenia składników dla platformy .NET i platformy uniwersalnej systemu Windows