Partage via


Boxing (C++/ CLI et C++/CX)

La conversion des types valeur en objets est appelée boxing, et la conversion d’objets en types valeur est appelée unboxing.

Tous les runtimes

(Aucune remarque pour cette fonctionnalité de langage ne s’applique à tous les runtimes.)

Windows Runtime

C++/CX prend en charge une syntaxe sténographique pour les types valeur boxing et les types référence unboxing. Un type valeur est boxed quand il est assigné à une variable de type Object. Une variable Object est unboxed quand elle est assignée à une variable de type valeur et que le type unboxed est spécifié entre parenthèses ; autrement dit, quand la variable objet est convertie en type valeur.

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

Spécifications

Option du compilateur : /ZW

Exemples

L'exemple de code suivant effectue une opération boxing et une opération unboxing sur une valeur DateTime. Tout d’abord, l’exemple obtient une valeur DateTime qui représente la date et l’heure actuelles et l’assigne à une variable DateTime. Ensuite, une opération boxing est effectuée sur la valeur DateTime en l’assignant à une variable Object. Enfin, la valeur boxed est unboxed en l’assignant à une autre variable DateTime.

Pour tester l’exemple, créez un projet BlankApplication, remplacez la méthode BlankPage::OnNavigatedTo(), puis spécifiez les points d’arrêt au crochet fermant et l’attribution à la variable str1. Quand l’exemple atteint le crochet fermant, examinez str1.

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

Pour plus d’informations, consultez Boxing (C++/CX).

Common Language Runtime

Le compilateur convertit des types valeur en Object. Cette opération est possible en raison d'une conversion définie par le compilateur pour convertir des types valeur en Object.

Les opérations boxing et unboxing permettent de traiter les types valeur en tant qu'objets. Les types valeur, y compris les types struct et les types intégrés comme int, peuvent être convertis en et à partir du type Object.

Pour en savoir plus, consultez :

Spécifications

Option du compilateur : /clr

Exemples

L'exemple suivant montre comment fonctionne le boxing implicite.

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

Voir aussi

Extensions de composants pour .NET et UWP