Freigeben über


Boxing- und Unboxing-Werte für IInspectable mit C++/WinRT

Hinweis

Sie können nicht nur skalare Werte, sondern auch die meisten Arten von Arrays (mit Ausnahme von Arrays von Enumerationen) mithilfe der Funktionen winrt::box_value und winrt::unbox_value boxen und entboxen. Sie können nur skalare Werte entpacken, indem Sie die Funktion winrt::unbox_value_or verwenden.

Die IInspectable-Schnittstelle ist die Basisschnittstelle jeder Laufzeitklasse in der Windows-Runtime (WinRT). Dies ist eine analoge Idee, IUnknown sich an der Wurzel jeder COM-Schnittstelle und -Klasse befindet; und System.Object sich im Stamm jeder Common Type System Klasse befinden.

Mit anderen Worten: Einer Funktion, die IInspectable erwartet, kann eine Instanz jeder Laufzeitklasse übergeben werden. Sie können jedoch weder direkt an eine solche Funktion einen skalaren Wert (z. B. einen numerischen oder Textwert) noch ein Array übergeben. Stattdessen muss ein Skalar- oder Arraywert in ein Referenzklassenobjekt eingebettet werden. Dieser Umbruchprozess wird als Boxen Wert bezeichnet.

Von Bedeutung

Sie können jeden beliebigen Typ, den Sie an eine Windows-Runtime-API übergeben können, boxen und unboxen. Mit anderen Worten, ein Windows-Runtime-Typ. Numerische und Textwerte (Zeichenfolgen) und Arrays sind einige der oben angegebenen Beispiele. Ein weiteres Beispiel ist struct, die Sie in IDL definieren. Wenn Sie versuchen, eine normale C++-struct (eine, die nicht in IDL definiert ist) zu boxen, erinnert der Compiler Sie daran, dass Sie nur einen Windows-Runtime-Typ eingeben können. Eine Laufzeitklasse ist ein Windows-Runtime-Typ. Sie können jedoch selbstverständlich Laufzeitklassen an Windows-Runtime-APIs übergeben, ohne sie in ein Objekt zu verpacken.

C++/WinRT- stellt die winrt::box_value--Funktion bereit, die einen Skalar- oder Arraywert annimmt und den Wert in einem IInspectable-zurückgibt. Zum Entpacken eines IInspectable in einen Skalar- oder Arraywert gibt es die winrt::unbox_value-Funktion. Für das Zurückführen eines IInspectable in einen skalaren Wert gibt es auch die Funktion winrt::unbox_value_or.

Beispiele für das Boxen eines Werts

Die LaunchActivatedEventArgs::Arguments Accessor-Funktion gibt eine winrt::hstringzurück, welcher ein skalarer Wert ist. Wir können den hstring-Wert boxen und an eine Funktion übergeben, die IInspectable erwartet.

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    ...
    rootFrame.Navigate(winrt::xaml_typename<BlankApp1::MainPage>(), winrt::box_value(e.Arguments()));
    ...
}

Um die Inhaltseigenschaft eines XAML-Button-festzulegen, rufen Sie die Funktion Button::Content Mutator auf. Um die Inhaltseigenschaft auf einen Zeichenfolgenwert festzulegen, können Sie diesen Code verwenden.

Button().Content(winrt::box_value(L"Clicked"));

Zunächst konvertiert der hstring-Konvertierungskonstruktor das Zeichenfolgenliteral in einen hstring. Dann wird die Überladung von winrt::box_value aufgerufen, die einen hstring akzeptiert.

Beispiele für das Entpacken einer IInspectable

In Ihren eigenen Funktionen, die IInspectableerwarten, können Sie winrt::unbox_value verwenden, um zu entpacken, und Sie können winrt::unbox_value_or verwenden, um mit einem Standardwert zu entpacken. Sie können auch try_as verwenden, um auf eine std::optionalzu entpacken.

void Unbox(winrt::Windows::Foundation::IInspectable const& object)
{
    hstring hstringValue = unbox_value<hstring>(object); // Throws if object is not a boxed string.
    hstringValue = unbox_value_or<hstring>(object, L"Default"); // Returns L"Default" if object is not a boxed string.
    float floatValue = unbox_value_or<float>(object, 0.f); // Returns 0.0 if object is not a boxed float.
    std::optional<int> optionalInt = object.try_as<int>(); // Returns std::nullopt if object is not a boxed int.
}

Bestimmen Sie den Typ eines verpackten Werts

Wenn Sie einen eingebetteten Wert erhalten und sich nicht sicher sind, welchen Typ er enthält (Sie müssen den Typ kennen, um ihn zu entpacken), können Sie den eingebetteten Wert über seine IPropertyValue--Schnittstelle abfragen und dann Type aufrufen. Hier ist ein Codebeispiel.

WINRT_ASSERT ist eine Makrodefinition und expandiert zu _ASSERTE.

float pi = 3.14f;
auto piInspectable = winrt::box_value(pi);
auto piPropertyValue = piInspectable.as<winrt::Windows::Foundation::IPropertyValue>();
WINRT_ASSERT(piPropertyValue.Type() == winrt::Windows::Foundation::PropertyType::Single);

Wichtige APIs