Composants Windows Runtime avec C# et Visual BasicWindows Runtime components with C# and Visual Basic

Vous pouvez utiliser du code managé pour créer vos propres types de Windows Runtime et les empaqueter dans un composant Windows Runtime.You can use managed code to create your own Windows Runtime types and package them in a Windows Runtime component. Vous pouvez utiliser votre composant dans les applications plateforme Windows universelle (UWP) écrites en C++, JavaScript, Visual Basic ou C#.You can use your component in Universal Windows Platform (UWP) apps that are written in C++, JavaScript, Visual Basic, or C#. Cette rubrique présente les règles de création d’un composant et décrit certains aspects de la prise en charge de .NET pour Windows Runtime.This topic outlines the rules for creating a component, and discusses some aspects of .NET support for the Windows Runtime. En règle générale, cette prise en charge est conçue pour être transparente pour les programmeurs .NET.In general, that support is designed to be transparent to the .NET programmer. Toutefois, lorsque vous créez un composant à utiliser avec JavaScript ou C++, vous devez tenir compte des différences de prise en charge de Windows Runtime par ces langages.However, when you create a component to use with JavaScript or C++, you need to be aware of differences in the way those languages support the Windows Runtime.

Si vous créez un composant à utiliser uniquement dans des applications UWP écrites en Visual Basic ou en C#, et que le composant ne contient pas de contrôles UWP, envisagez d’utiliser le modèle de bibliothèque de classes au lieu du modèle de projet de composant Windows Runtime dans Microsoft Visual Studio.If you are creating a component for use only in UWP apps that are written in Visual Basic or C#, and the component does not contain UWP controls, then consider using the Class Library template instead of the Windows Runtime Component project template in Microsoft Visual Studio. Il existe moins de restrictions sur une bibliothèque de classes simple.There are fewer restrictions on a simple class library.

Déclaration de types dans les composants Windows RuntimeDeclaring types in Windows Runtime components

En interne, les types de Windows Runtime dans votre composant peuvent utiliser toutes les fonctionnalités .NET autorisées dans une application UWP.Internally, the Windows Runtime types in your component can use any .NET functionality that's allowed in a UWP app. Pour plus d’informations, consultez .net pour les applications UWP.For more info, see .NET for UWP apps.

En externe, les membres de vos types peuvent exposer uniquement les types de Windows Runtime pour leurs paramètres et valeurs de retour.Externally, the members of your types can expose only Windows Runtime types for their parameters and return values. La liste suivante décrit les limitations sur les types .NET exposés à partir d’un composant Windows Runtime.The following list describes the limitations on .NET types that are exposed from a Windows Runtime component.

  • Les champs, paramètres et valeurs de retour de tous les types et membres publics de votre composant doivent être de type Windows Runtime.The fields, parameters, and return values of all the public types and members in your component must be Windows Runtime types. Cette restriction comprend les types de Windows Runtime que vous créez ainsi que les types fournis par le Windows Runtime lui-même.This restriction includes the Windows Runtime types that you author as well as types that are provided by the Windows Runtime itself. Il comprend également un certain nombre de types .NET.It also includes a number of .NET types. L’inclusion de ces types fait partie de la prise en charge fournie par .NET pour permettre l’utilisation naturelle de l’Windows Runtime en code managé — . votre code semble utiliser des types .net familiers à la place des types de Windows Runtime sous-jacents.The inclusion of these types is part of the support that .NET provides to enable the natural use of the Windows Runtime in managed code—your code appears to use familiar .NET types instead of the underlying Windows Runtime types. Par exemple, vous pouvez utiliser des types primitifs .NET tels que Int32 et double, certains types fondamentaux tels que DateTimeOffset et URI, et certains types d’interfaces génériques couramment utilisés tels que **ienumerable < T > ** (IEnumerable (Of T) dans Visual Basic) et **IDictionary < TKey, TValue > **.For example, you can use .NET primitive types such as Int32 and Double, certain fundamental types such as DateTimeOffset and Uri, and some commonly used generic interface types such as IEnumerable<T> (IEnumerable(Of T) in Visual Basic) and IDictionary<TKey,TValue>. Notez que les arguments de type de ces types génériques doivent être des types Windows Runtime.Note that the type arguments of these generic types must be Windows Runtime types. Ce sujet est abordé dans les sections transmission de Windows Runtime types au code managé et passage de types managés à la Windows Runtime, plus loin dans cette rubrique.This is discussed in the sections Passing Windows Runtime types to managed code and Passing managed types to the Windows Runtime, later in this topic.

  • Les interfaces et classes publiques peuvent contenir des méthodes, propriétés et événements.Public classes and interfaces can contain methods, properties, and events. Vous pouvez déclarer des délégués pour vos événements ou utiliser le délégué < EventHandler > T .You can declare delegates for your events, or use the EventHandler<T> delegate. Une classe ou une interface publique ne peut pas :A public class or interface can't:

    • être générique ;Be generic.
    • Implémentez une interface qui n’est pas une interface Windows Runtime (Toutefois, vous pouvez créer vos propres interfaces Windows Runtime et les implémenter).Implement an interface that is not a Windows Runtime interface (however, you can create your own Windows Runtime interfaces and implement them).
    • Dérivez des types qui ne sont pas dans le Windows Runtime, tels que System. exception et System. EventArgs.Derive from types that are not in the Windows Runtime, such as System.Exception and System.EventArgs.
  • Tous les types publics doivent posséder un espace de noms racine qui correspond au nom de l’assembly, et le nom de l’assembly ne doit pas commencer par « Windows ».All public types must have a root namespace that matches the assembly name, and the assembly name must not begin with "Windows".

    Conseil.Tip. Par défaut, les projets Visual Studio ont des noms d'espaces de noms qui correspondent au nom de l'assembly.By default, Visual Studio projects have namespace names that match the assembly name. En Visual Basic, la déclaration d’espace de noms pour cet espace de noms par défaut n’est pas affichée dans votre code.In Visual Basic, the Namespace statement for this default namespace is not shown in your code.

  • Les structures publiques ne peuvent pas avoir d’autres membres que les champs publics, et ces champs doivent être des types de valeur ou des chaînes.Public structures can't have any members other than public fields, and those fields must be value types or strings.

  • Les classes publiques doivent être sealed (NotInheritable en Visual Basic).Public classes must be sealed (NotInheritable in Visual Basic). Si votre modèle de programmation requiert le polymorphisme, vous pouvez créer une interface publique et implémenter cette interface sur les classes qui doivent être polymorphes.If your programming model requires polymorphism, then you can create a public interface, and implement that interface on the classes that must be polymorphic.

Débogage de votre composantDebugging your component

Si votre application UWP et votre composant sont générés avec du code managé, vous pouvez les déboguer tous les deux en même temps.If both your UWP app and your component are built with managed code, then you can debug them both at the same time.

Lorsque vous testez votre composant dans le cadre d’une application UWP à l’aide de C++, vous pouvez déboguer le code managé et natif en même temps.When you're testing your component as part of a UWP app using C++, you can debug managed and native code at the same time. La valeur par défaut est uniquement le code natif.The default is native code only.

Pour déboguer à la fois du code C++ natif et du code managéTo debug both native C++ code and managed code

  1. Ouvrez le menu contextuel de votre projet Visual C++, puis choisissez Propriétés.Open the shortcut menu for your Visual C++ project, and choose Properties.
  2. Dans les pages de propriétés, sous Propriétés de configuration, choisissez Débogage.In the property pages, under Configuration Properties, choose Debugging.
  3. Choisissez Type de débogueur, et dans la zone de liste déroulante remplacez la valeur Natif uniquement par Mixte (managé et natif).Choose Debugger Type, and in the drop-down list box change Native Only to Mixed (Managed and Native). Choisissez OK.Choose OK.
  4. Définissez des points d’arrêt dans le code natif et le code managé.Set breakpoints in native and managed code.

Lorsque vous testez votre composant dans le cadre d’une application UWP à l’aide de JavaScript, par défaut, la solution est en mode de débogage JavaScript.When you're testing your component as part of a UWP app using JavaScript, by default the solution is in JavaScript debugging mode. Dans Visual Studio, vous ne pouvez pas déboguer du code JavaScript et du code managé en même temps.In Visual Studio, you can't debug JavaScript and managed code at the same time.

Pour déboguer du code managé au lieu de JavaScriptTo debug managed code instead of JavaScript

  1. Ouvrez le menu contextuel de votre projet JavaScript, puis choisissez Propriétés.Open the shortcut menu for your JavaScript project, and choose Properties.
  2. Dans les pages de propriétés, sous Propriétés de configuration, choisissez Débogage.In the property pages, under Configuration Properties, choose Debugging.
  3. Choisissez Type de débogueur, et dans la zone de liste déroulante remplacez la valeur Script uniquement par Managé uniquement.Choose Debugger Type, and in the drop-down list box change Script Only to Managed Only. Choisissez OK.Choose OK.
  4. Définissez des points d’arrêt dans le code managé et déboguez comme d’habitude.Set breakpoints in managed code and debug as usual.

Passage de types Windows Runtime au code managéPassing Windows Runtime types to managed code

Comme mentionné précédemment dans la section déclaration des types dans les composants Windows Runtime, certains types .NET peuvent apparaître dans les signatures des membres des classes publiques.As mentioned previously in the section Declaring types in Windows Runtime components, certain .NET types can appear in the signatures of members of public classes. Cela fait partie de la prise en charge fournie par .NET pour permettre l’utilisation naturelle de l’Windows Runtime dans du code managé.This is part of the support that .NET provides to enable the natural use of the Windows Runtime in managed code. Elle inclut des types primitifs et certaines classes et interfaces.It includes primitive types and some classes and interfaces. Lorsque votre composant est utilisé à partir de JavaScript, ou à partir du code C++, il est important de savoir comment vos types .NET apparaissent à l’appelant.When your component is used from JavaScript, or from C++ code, it's important to know how your .NET types appear to the caller. Pour obtenir des exemples avec JavaScript , consultez Procédure pas à pas de création d’un composant C# ou Visual Basic Windows Runtime et appel de ce dernier à partir de JavaScript .See Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript for examples with JavaScript. Cette section aborde les types couramment utilisés.This section discusses commonly used types.

Dans .NET, les types primitifs tels que la structure Int32 ont de nombreuses propriétés et méthodes utiles, telles que la méthode TryParse .In .NET, primitive types such as the Int32 structure have many useful properties and methods, such as the TryParse method. En revanche, les structures et types primitifs dans le Windows Runtime ont uniquement des champs.By contrast, primitive types and structures in the Windows Runtime only have fields. Quand vous transmettez ces types au code managé, ils semblent être des types .NET et vous pouvez utiliser les propriétés et les méthodes des types .NET comme vous le feriez normalement.When you pass these types to managed code, they appear to be .NET types, and you can use the properties and methods of .NET types as you normally would. La liste suivante récapitule les substitutions effectuées automatiquement dans l’IDE :The following list summarizes the substitutions that are made automatically in the IDE:

  • Pour les primitives de Windows Runtime Int32, Int64, Single, double, Boolean, String (une collection immuable de caractères Unicode), enum, UInt32, UInt64et GUID, utilisez le type du même nom dans l’espace de noms System.For the Windows Runtime primitives Int32, Int64, Single, Double, Boolean, String (an immutable collection of Unicode characters), Enum, UInt32, UInt64, and Guid, use the type of the same name in the System namespace.
  • Pour UInt8, utilisez System. Byte.For UInt8, use System.Byte.
  • Pour Char16, utilisez System. Char.For Char16, use System.Char.
  • Pour l’interface IInspectable , utilisez System. Object.For the IInspectable interface, use System.Object.

Si C# ou Visual Basic fournit un mot clé de langage pour l’un de ces types, vous pouvez utiliser le mot clé de langage à la place.If C# or Visual Basic provides a language keyword for any of these types, then you can use the language keyword instead.

En plus des types primitifs, certains types de Windows Runtime de base, couramment utilisés, apparaissent dans du code managé comme leurs équivalents .NET.In addition to primitive types, some basic, commonly used Windows Runtime types appear in managed code as their .NET equivalents. Par exemple, supposons que votre code JavaScript utilise la classe Windows. Foundation. Uri , et que vous souhaitez le passer à une méthode C# ou Visual Basic.For example, suppose your JavaScript code uses the Windows.Foundation.Uri class, and you want to pass it to a C# or Visual Basic method. Le type équivalent dans le code managé est la classe .NET System. Uri , et il s’agit du type à utiliser pour le paramètre de la méthode.The equivalent type in managed code is the .NET System.Uri class, and that's the type to use for the method parameter. Vous pouvez savoir quand un type de Windows Runtime apparaît en tant que type .NET, car IntelliSense dans Visual Studio masque le type de Windows Runtime lorsque vous écrivez du code managé et présente le type .NET équivalent.You can tell when a Windows Runtime type appears as a .NET type, because IntelliSense in Visual Studio hides the Windows Runtime type when you're writing managed code, and presents the equivalent .NET type. (Généralement les deux types ont le même nom.(Usually the two types have the same name. Toutefois, Notez que la structure Windows. Foundation. DateTime apparaît dans le code managé sous la forme System. DateTimeOffset et non en tant que System. DateTime.)However, note that the Windows.Foundation.DateTime structure appears in managed code as System.DateTimeOffset and not as System.DateTime.)

Pour certains types de collections couramment utilisés, le mappage s’effectue entre les interfaces implémentées par un type Windows Runtime et les interfaces implémentées par le type .NET correspondant.For some commonly used collection types, the mapping is between the interfaces that are implemented by a Windows Runtime type and the interfaces that are implemented by the corresponding .NET type. Comme pour les types mentionnés ci-dessus, vous déclarez des types de paramètres à l’aide du type .NET.As with the types mentioned above, you declare parameter types by using the .NET type. Cela masque certaines différences entre les types et rend l’écriture du code .NET plus naturelle.This hides some differences between the types and makes writing .NET code more natural.

Le tableau suivant répertorie les types d’interface générique les plus courants, ainsi que d’autres classes et mappages d’interface courants.The following table lists the most common of these generic interface types, along with other common class and interface mappings. Pour obtenir la liste complète des types de Windows Runtime mappés par .NET, consultez mappages .net des types de Windows Runtime.For a complete list of Windows Runtime types that .NET maps, see .NET mappings of Windows Runtime types.

Windows RuntimeWindows Runtime .NET.NET
IIterable<T>IIterable<T> IEnumerable < T>IEnumerable<T>
IVector<T>IVector<T> IList < T>IList<T>
IVectorView<T>IVectorView<T> IReadOnlyList < T>IReadOnlyList<T>
IMap < K, V>IMap<K, V> IDictionary < TKey, TValue>IDictionary<TKey, TValue>
IMapView<K, V>IMapView<K, V> IReadOnlyDictionary < TKey, TValue>IReadOnlyDictionary<TKey, TValue>
IKeyValuePair < K, V>IKeyValuePair<K, V> KeyValuePair < TKey, TValue>KeyValuePair<TKey, TValue>
IBindableIterableIBindableIterable IEnumerableIEnumerable
IBindableVectorIBindableVector IListIList
Windows.UI.Xaml.Data.INotifyPropertyChangedWindows.UI.Xaml.Data.INotifyPropertyChanged System.ComponentModel.INotifyPropertyChangedSystem.ComponentModel.INotifyPropertyChanged
Windows.UI.Xaml.Data.PropertyChangedEventHandlerWindows.UI.Xaml.Data.PropertyChangedEventHandler System.ComponentModel.PropertyChangedEventHandlerSystem.ComponentModel.PropertyChangedEventHandler
Windows.UI.Xaml.Data.PropertyChangedEventArgsWindows.UI.Xaml.Data.PropertyChangedEventArgs System.ComponentModel.PropertyChangedEventArgsSystem.ComponentModel.PropertyChangedEventArgs

Lorsqu’un type implémente plusieurs interfaces, vous pouvez utiliser n’importe quelle interface qu’il implémente comme type de paramètre ou type de retour d’un membre.When a type implements more than one interface, you can use any of the interfaces it implements as a parameter type or return type of a member. Par exemple, vous pouvez passer ou retourner un **dictionnaire < int, String > ** (**dictionary (Of Integer, String)** dans Visual Basic) As **IDictionary < int, String > **, **IReadOnlyDictionary < int, String > **ou **IEnumerable < System. Collections. Generic. KeyValuePair < TKey, TValue > > **.For example, you can pass or return a Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) as IDictionary<int, string>, IReadOnlyDictionary<int, string>, or IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>.

Important

JavaScript utilise l'interface qui apparaît en premier dans la liste des interfaces implémentées par un type managé.JavaScript uses the interface that appears first in the list of interfaces that a managed type implements. Par exemple, si vous retournez **Dictionary < int, String > ** to JavaScript code, il apparaît comme **IDictionary < int, String > ** , quelle que soit l’interface que vous spécifiez comme type de retour.For example, if you return Dictionary<int, string> to JavaScript code, it appears as IDictionary<int, string> no matter which interface you specify as the return type. Cela signifie que si la première interface n’inclut pas un membre qui apparaît sur les interfaces ultérieures, ce membre n’est pas visible pour JavaScript.This means that if the first interface doesn't include a member that appears on later interfaces, that member isn't visible to JavaScript.

Dans le Windows Runtime, **IMap < k, v > ** et **IMapView < k, v > ** sont itérés à l’aide de IKeyValuePair.In the Windows Runtime, IMap<K, V> and IMapView<K, V> are iterated by using IKeyValuePair. Quand vous les transmettez à du code managé, elles apparaissent sous la forme **IDictionary < TKey, TValue > ** et **IReadOnlyDictionary < TKey, TValue > **, si bien que naturellement, vous utilisez **System. Collections. Generic. KeyValuePair < TKey, TValue > ** pour les énumérer.When you pass them to managed code, they appear as IDictionary<TKey, TValue> and IReadOnlyDictionary<TKey, TValue>, so naturally you use System.Collections.Generic.KeyValuePair<TKey, TValue> to enumerate them.

La façon dont les interfaces apparaissent dans le code managé affecte la façon dont les types qui implémentent ces interfaces apparaissent.The way interfaces appear in managed code affects the way types that implement these interfaces appear. Par exemple, la classe PropertySet implémente **IMap < K, V > **, qui apparaît dans le code managé comme IDictionary < TKey, > TValue.For example, the PropertySet class implements IMap<K, V>, which appears in managed code as IDictionary<TKey, TValue>. PropertySet s’affiche comme s’il implémentait IDictionary < TKey > , TValue au lieu de IMap < K, > V, donc en code managé, il semble avoir une méthode Add , qui se comporte comme la méthode Add sur les dictionnaires .net.PropertySet appears as if it implemented IDictionary<TKey, TValue> instead of IMap<K, V>, so in managed code it appears to have an Add method, which behaves like the Add method on .NET dictionaries. Il ne semble pas avoir une méthode Insert .It doesn't appear to have an Insert method. Vous pouvez voir cet exemple dans la rubrique procédure pas à pas de création d’un composant C# ou Visual Basic Windows Runtime et appel de ce dernier à partir de JavaScript.You can see this example in the topic Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Passage de types managés au Windows RuntimePassing managed types to the Windows Runtime

Comme indiqué dans la section précédente, certains types de Windows Runtime peuvent apparaître en tant que types .NET dans les signatures des membres de votre composant, ou dans les signatures des membres Windows Runtime quand vous les utilisez dans l’IDE.As discussed in the previous section, some Windows Runtime types can appear as .NET types in the signatures of your component's members, or in the signatures of Windows Runtime members when you use them in the IDE. Lorsque vous transmettez des types .NET à ces membres ou que vous les utilisez comme valeurs de retour des membres de votre composant, ils apparaissent dans le code de l’autre côté en tant que type de Windows Runtime correspondant.When you pass .NET types to these members or use them as the return values of your component's members, they appear to the code on the other side as the corresponding Windows Runtime type. Pour obtenir des exemples des effets que cela peut avoir quand votre composant est appelé à partir de JavaScript, consultez la section « retour des types managés à partir de votre composant » dans procédure pas à pas de création d’un composant C# ou Visual Basic Windows Runtime, et appel de ce dernier à partir de JavaScript.For examples of the effects this can have when your component is called from JavaScript, see the "Returning managed types from your component" section in Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Méthodes surchargéesOverloaded methods

Dans le Windows Runtime, les méthodes peuvent être surchargées.In the Windows Runtime, methods can be overloaded. Toutefois, si vous déclarez plusieurs surcharges avec le même nombre de paramètres, vous devez appliquer l’attribut Windows. Foundation. Metadata. DefaultOverloadAttribute à une seule de ces surcharges.However, if you declare multiple overloads with the same number of parameters, you must apply the Windows.Foundation.Metadata.DefaultOverloadAttribute attribute to only one of those overloads. Cette surcharge est la seule que vous pouvez appeler depuis JavaScript.That overload is the only one you can call from JavaScript. Par exemple, dans le code suivant la surcharge qui prend int (Integer en Visual Basic) est la surcharge par défaut.For example, in the following code the overload that takes an int (Integer in Visual Basic) is the default overload.

public string OverloadExample(string s)
{
    return s;
}

[Windows.Foundation.Metadata.DefaultOverload()]
public int OverloadExample(int x)
{
    return x;
}
Public Function OverloadExample(ByVal s As String) As String
    Return s
End Function

<Windows.Foundation.Metadata.DefaultOverload> _
Public Function OverloadExample(ByVal x As Integer) As Integer
    Return x
End Function

PRÉCIEUSE JavaScript vous permet de passer n’importe quelle valeur à OverloadExampleet convertit la valeur en type requis par le paramètre.[IMPORTANT] JavaScript allows you to pass any value to OverloadExample, and coerces the value to the type that is required by the parameter. Vous pouvez appeler OverloadExample avec « 42 », « 42 » ou 42,3, mais toutes ces valeurs sont passées à la surcharge par défaut.You can call OverloadExample with "forty-two", "42", or 42.3, but all those values are passed to the default overload. La surcharge par défaut dans l’exemple précédent retourne 0, 42 et 42, respectivement.The default overload in the previous example returns 0, 42, and 42, respectively.

Vous ne pouvez pas appliquer l’attribut DefaultOverloadAttribute aux constructeurs.You can't apply the DefaultOverloadAttribute attribute to constructors. Tous les constructeurs d’une classe doivent avoir des numéros de paramètres différents.All the constructors in a class must have different numbers of parameters.

Implémentation d’IStringableImplementing IStringable

À partir de Windows 8.1, le Windows Runtime inclut une interface IStringable dont la méthode unique, IStringable. ToString, fournit une prise en charge de base de la mise en forme comparable à celle fournie par Object. ToString.Starting with Windows 8.1, the Windows Runtime includes an IStringable interface whose single method, IStringable.ToString, provides basic formatting support comparable to that provided by Object.ToString. Si vous choisissez d’implémenter IStringable dans un type managé public qui est exporté dans un composant Windows Runtime, les restrictions suivantes s’appliquent :If you do choose to implement IStringable in a public managed type that is exported in a Windows Runtime component, the following restrictions apply:

  • Vous pouvez définir l’interface IStringable uniquement dans une relation « la classe implémente », par exemple le code suivant en C# :You can define the IStringable interface only in a "class implements" relationship, such as the following code in C#:

    public class NewClass : IStringable
    

    Ou le code Visual Basic suivant :Or the following Visual Basic code:

    Public Class NewClass : Implements IStringable
    
  • Vous ne pouvez pas implémenter IStringable sur une interface.You can't implement IStringable on an interface.

  • Vous ne pouvez pas déclarer un paramètre de type IStringable.You can't declare a parameter to be of type IStringable.

  • IStringable ne peut pas être le type de retour d’une méthode, d’une propriété ou d’un champ.IStringable can't be the return type of a method, property, or field.

  • Vous ne pouvez pas masquer votre implémentation IStringable à partir des classes de base à l’aide d’une définition de méthode telle que la suivante :You can't hide your IStringable implementation from base classes by using a method definition such as the following:

    public class NewClass : IStringable
    {
       public new string ToString()
       {
          return "New ToString in NewClass";
       }
    }
    

    Au lieu de cela, l’implémentation de IStringable. ToString doit toujours remplacer l’implémentation de la classe de base.Instead, the IStringable.ToString implementation must always override the base class implementation. Vous pouvez masquer une implémentation ToString uniquement en l’appelant sur une instance de classe fortement typée.You can hide a ToString implementation only by invoking it on a strongly typed class instance.

Notes

Dans diverses conditions, les appels de code natif à un type managé qui implémente IStringable ou masquent son implémentation ToString peuvent entraîner un comportement inattendu.Under a variety of conditions, calls from native code to a managed type that implements IStringable or hides its ToString implementation can produce unexpected behavior.

Opérations asynchronesAsynchronous operations

Pour implémenter une méthode asynchrone dans votre composant, ajoutez « Async » à la fin du nom de la méthode et retournez l’une des interfaces Windows Runtime qui représentent des actions ou des opérations asynchrones : IAsyncAction, **IAsyncActionWithProgress < TProgress > **, **IAsyncOperation < TResult > **ou **IAsyncOperationWithProgress < TResult, TProgress > **.To implement an asynchronous method in your component, add "Async" to the end of the method name and return one of the Windows Runtime interfaces that represent asynchronous actions or operations: IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult>, or IAsyncOperationWithProgress<TResult, TProgress>.

Vous pouvez utiliser des tâches .NET (la classe de tâche et la classe de ** < > tâche** générique) pour implémenter votre méthode asynchrone.You can use .NET tasks (the Task class and generic Task<TResult> class) to implement your asynchronous method. Vous devez retourner une tâche qui représente une opération en cours, telle qu’une tâche retournée à partir d’une méthode asynchrone écrite en C# ou Visual Basic, ou une tâche retournée à partir de la méthode Task. Run .You must return a task that represents an ongoing operation, such as a task that is returned from an asynchronous method written in C# or Visual Basic, or a task that is returned from the Task.Run method. Si vous utilisez un constructeur pour créer la tâche, vous devez appeler sa méthode Task.Start avant de la retourner.If you use a constructor to create the task, you must call its Task.Start method before returning it.

Une méthode qui utilise await ( Await dans Visual Basic) requiert le async mot clé ( Async dans Visual Basic).A method that uses await (Await in Visual Basic) requires the async keyword (Async in Visual Basic). Si vous exposez une telle méthode à partir d’un composant Windows Runtime, appliquez le async mot clé au délégué que vous transmettez à la méthode Run .If you expose such a method from a Windows Runtime component, apply the async keyword to the delegate that you pass to the Run method.

Pour les actions et opérations asynchrones qui ne prennent pas en charge l’annulation ou le rapport de progression, vous pouvez utiliser la méthode d’extension WindowsRuntimeSystemExtensions.AsAsyncAction ou AsAsyncOperation<TResult> pour encapsuler la tâche dans l’interface appropriée.For asynchronous actions and operations that do not support cancellation or progress reporting, you can use the WindowsRuntimeSystemExtensions.AsAsyncAction or AsAsyncOperation<TResult> extension method to wrap the task in the appropriate interface. Par exemple, le code suivant implémente une méthode asynchrone à l’aide de la méthode **Task. Run < TResult > ** pour démarrer une tâche.For example, the following code implements an asynchronous method by using the Task.Run<TResult> method to start a task. La méthode d’extension **AsAsyncOperation < TResult > ** retourne la tâche sous la forme d’une opération asynchrone Windows Runtime.The AsAsyncOperation<TResult> extension method returns the task as a Windows Runtime asynchronous operation.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return Task.Run<IList<string>>(async () =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    }).AsAsyncOperation();
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
     As IAsyncOperation(Of IList(Of String))

    Return Task.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function).AsAsyncOperation()
End Function

Le code JavaScript suivant montre comment la méthode peut être appelée à l’aide d’un objet WinJS. promise.The following JavaScript code shows how the method could be called by using a WinJS.Promise object. La fonction qui est passée à la méthode then est exécutée lorsque l’appel asynchrone se termine.The function that is passed to the then method is executed when the asynchronous call completes. Le paramètre stringList contient la liste des chaînes retournées par la méthode DownloadAsStringAsync , et la fonction effectue le traitement requis.The stringList parameter contains the list of strings that is returned by the DownloadAsStringAsync method, and the function does whatever processing is required.

function asyncExample(id) {

    var result = SampleComponent.Example.downloadAsStringAsync(id).then(
        function (stringList) {
            // Place code that uses the returned list of strings here.
        });
}

Pour les actions et les opérations asynchrones qui prennent en charge l’annulation ou le rapport de progression, utilisez la classe AsyncInfo pour générer une tâche démarrée et pour raccorder les fonctionnalités d’annulation et de rapport de progression de la tâche avec les fonctionnalités d’annulation et de rapport de progression de l’interface de Windows Runtime appropriée.For asynchronous actions and operations that support cancellation or progress reporting, use the AsyncInfo class to generate a started task and to hook up the cancellation and progress reporting features of the task with the cancellation and progress reporting features of the appropriate Windows Runtime interface. Pour obtenir un exemple qui prend en charge à la fois l’annulation et le rapport de progression, consultez procédure pas à pas de création d’un composant C# ou Visual Basic Windows Runtime et appel de ce dernier à partir de JavaScript.For an example that supports both cancellation and progress reporting, see Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Notez que vous pouvez utiliser les méthodes de la classe AsyncInfo même si votre méthode asynchrone ne prend pas en charge l’annulation ou le rapport de progression.Note that you can use the methods of the AsyncInfo class even if your asynchronous method doesn't support cancellation or progress reporting. Si vous utilisez une Visual Basic fonction lambda ou une méthode anonyme C#, ne fournissez pas de paramètres pour le jeton et l’interface **IProgress < t > ** .If you use a Visual Basic lambda function or a C# anonymous method, don't supply parameters for the token and IProgress<T> interface. Si vous utilisez une fonction lambda en C#, fournissez un paramètre de jeton, mais ignorez-le.If you use a C# lambda function, supply a token parameter but ignore it. L’exemple précédent, qui utilisait la < méthode AsAsyncOperation TResult > , se présente comme suit quand vous utilisez la surcharge de méthode **AsyncInfo. Run < TResult > (Func < CancellationToken, Task < TResult > > **) à la place.The previous example, which used the AsAsyncOperation<TResult> method, looks like this when you use the AsyncInfo.Run<TResult>(Func<CancellationToken, Task<TResult>>) method overload instead.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return AsyncInfo.Run<IList<string>>(async (token) =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    });
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
    As IAsyncOperation(Of IList(Of String))

    Return AsyncInfo.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function)
End Function

Si vous créez une méthode asynchrone qui prend éventuellement en charge l’annulation ou le rapport de progression, envisagez d’ajouter des surcharges qui n’ont pas de paramètres pour un jeton d’annulation ou l’interface **IProgress < t > ** .If you create an asynchronous method that optionally supports cancellation or progress reporting, consider adding overloads that don't have parameters for a cancellation token or the IProgress<T> interface.

Levée des exceptionsThrowing exceptions

Vous pouvez lever n’importe quel type d’exception inclus dans les applications .NET pour Windows.You can throw any exception type that is included in the .NET for Windows apps. Vous ne pouvez pas déclarer vos propres types d’exceptions publics dans un composant Windows Runtime, mais vous pouvez déclarer et lever des types non publics.You can't declare your own public exception types in a Windows Runtime component, but you can declare and throw non-public types.

Si votre composant ne gère pas l’exception, une exception correspondante est levée dans le code qui appelle votre composant.If your component doesn't handle the exception, a corresponding exception is raised in the code that called your component. La façon dont l’exception s’affiche pour l’appelant dépend de la méthode dont son langage prend en charge Windows Runtime.The way the exception appears to the caller depends on the way the calling language supports the Windows Runtime.

  • Dans JavaScript, l’exception s’affiche en tant qu’objet dans lequel le message d’exception est remplacé par une trace de la pile.In JavaScript, the exception appears as an object in which the exception message is replaced by a stack trace. Lorsque vous déboguez votre application dans Visual Studio, vous pouvez voir le texte du message d’origine affiché dans la boîte de dialogue d’exception du débogueur identifié comme « Informations WinRT ».When you debug your app in Visual Studio, you can see the original message text displayed in the debugger exception dialog box, identified as "WinRT Information". Vous ne pouvez pas accéder au texte du message d’origine à partir du code JavaScript.You can't access the original message text from JavaScript code.

    Conseil.Tip.La trace de la pile contient actuellement le type d'exception managé, mais nous ne vous recommandons pas d'analyser la trace pour identifier le type d'exception. Currently, the stack trace contains the managed exception type, but we don't recommend parsing the trace to identify the exception type. Utilisez plutôt une valeur HRESULT comme décrit plus loin dans cette section.Instead, use an HRESULT value as described later in this section.

  • En C++, l’exception s’affiche comme une exception de plateforme.In C++, the exception appears as a platform exception. Si la propriété HResult de l’exception managée peut être mappée à la valeur HRESULT d’une exception de plateforme spécifique, l’exception spécifique est utilisée. dans le cas contraire, une exception Platform :: COMException est levée.If the managed exception's HResult property can be mapped to the HRESULT of a specific platform exception, the specific exception is used; otherwise, a Platform::COMException exception is thrown. Le texte du message de l’exception managée n’est pas disponible pour le code C++.The message text of the managed exception is not available to C++ code. Si une exception de plateforme spécifique est levée, le texte du message par défaut pour ce type d’exception apparaît. Dans le cas contraire, aucun texte de message n’apparaît.If a specific platform exception was thrown, the default message text for that exception type appears; otherwise, no message text appears. Voir Exceptions (C++/CX).See Exceptions (C++/CX).

  • En C# ou Visual Basic, l’exception est une exception managée normale.In C# or Visual Basic, the exception is a normal managed exception.

Lorsque vous levez une exception de votre composant, vous pouvez permettre plus facilement à l’appelant JavaScript ou C++ de gérer l’exception en levant un type d’exception non public dont la valeur de la propriété HResult est spécifique à votre composant.When you throw an exception from your component, you can make it easier for a JavaScript or C++ caller to handle the exception by throwing a non-public exception type whose HResult property value is specific to your component. HRESULT est disponible pour un appelant JavaScript via la propriété Number de l’objet exception et à un appelant C++ via la propriété COMException :: HRESULT .The HRESULT is available to a JavaScript caller through the exception object's number property, and to a C++ caller through the COMException::HResult property.

Notes

Utilisez une valeur négative pour votre HRESULT.Use a negative value for your HRESULT. Une valeur positive est interprétée comme une réussite et aucune exception n’est levée dans l’appelant JavaScript ou C++.A positive value is interpreted as success, and no exception is thrown in the JavaScript or C++ caller.

Déclaration et déclenchement des événementsDeclaring and raising events

Lorsque vous déclarez un type pour contenir les données de votre événement, dérivez de Object au lieu de EventArgs, car EventArgs n’est pas un type Windows Runtime.When you declare a type to hold the data for your event, derive from Object instead of from EventArgs, because EventArgs is not a Windows Runtime type. Utilisez **EventHandler < TEventArgs > ** comme type de l’événement et utilisez votre type d’argument d’événement comme argument de type générique.Use EventHandler<TEventArgs> as the type of the event, and use your event argument type as the generic type argument. Déclenchez l’événement comme vous le feriez dans une application .NET.Raise the event just as you would in a .NET application.

Lorsque votre composant Windows Runtime est utilisé à partir de JavaScript ou C++, l’événement suit le modèle d’événement Windows Runtime attendu par ces langages.When your Windows Runtime component is used from JavaScript or C++, the event follows the Windows Runtime event pattern that those languages expect. Quand vous utilisez le composant à partir de C# ou de Visual Basic, l’événement apparaît comme un événement .NET ordinaire.When you use the component from C# or Visual Basic, the event appears as an ordinary .NET event. Un exemple est fourni dans procédure pas à pas de création d’un composant C# ou Visual Basic Windows Runtime, et appel de ce dernier à partir de JavaScript.An example is provided in Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Si vous implémentez les accesseurs d’événement personnalisés (si vous déclarez un événement avec le mot-clé Custom en Visual Basic), vous devez suivre le modèle d’événement Windows Runtime dans votre implémentation.If you implement custom event accessors (declare an event with the Custom keyword, in Visual Basic), you must follow the Windows Runtime event pattern in your implementation. Consultez événements personnalisés et accesseurs d’événement dans Windows Runtime composants.See Custom events and event accessors in Windows Runtime components. Notez que lorsque vous gérez l’événement à partir de C# ou de Visual Basic Code, il semble toujours être un événement .NET ordinaire.Note that when you handle the event from C# or Visual Basic code, it still appears to be an ordinary .NET event.

Étapes suivantesNext steps

Une fois que vous avez créé un composant Windows Runtime pour votre propre usage, vous découvrirez peut-être que la fonctionnalité qu’il encapsule est utile à d’autres développeurs.After you’ve created a Windows Runtime component for your own use, you may find that the functionality it encapsulates is useful to other developers. Vous avez deux possibilités pour empaqueter un composant afin de le distribuer à d’autres développeurs.You have two options for packaging a component for distribution to other developers. Voir Distribution d’un composant Windows Runtime managé.See Distributing a managed Windows Runtime component.

Pour plus d’informations sur les fonctionnalités du langage Visual Basic et C#, ainsi que sur la prise en charge de .NET pour l’Windows Runtime, consultez Visual Basic et référence du langage c#.For more information about Visual Basic and C# language features, and .NET support for the Windows Runtime, see Visual Basic and C# language reference.

DépannageTroubleshooting

SymptômeSymptom SolutionRemedy
Dans une application C++/WinRT, lors de l’utilisation d’un composant C# Windows Runtime qui utilise XAML, le compilateur génère une erreur au format «MyNamespace_XamlTypeInfo » : n’est pas membre de « WinRT :: MyNamespace », — où MyNamespace est le nom de l’espace de noms du composant Windows Runtime.In a C++/WinRT app, when consuming a C# Windows Runtime component that uses XAML, the compiler produces an error of the form "'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'"—where MyNamespace is the name of the Windows Runtime component's namespace. Dans pch.h , dans l’application/WinRT C++ consommatrice, ajoutez #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> — en remplaçant MyNamespace , le cas échéant.In pch.h in the consuming C++/WinRT app, add #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—replacing MyNamespace as appropriate.