Contrainte de type non managéUnmanaged type constraint

RésuméSummary

La fonctionnalité de contrainte non managée fournira la mise en œuvre du langage à la classe de types connus sous le nom de « types non managés » dans la spécification du langage C#. Cela est défini dans la section 18,2 comme un type qui n’est pas un type référence et ne contient pas de champs de type référence à aucun niveau d’imbrication.The unmanaged constraint feature will give language enforcement to the class of types known as "unmanaged types" in the C# language spec. This is defined in section 18.2 as a type which is not a reference type and doesn't contain reference type fields at any level of nesting.

MotivationMotivation

La motivation principale est de faciliter la création de code d’interopérabilité de bas niveau en C#.The primary motivation is to make it easier to author low level interop code in C#. Les types non managés sont l’un des principaux blocs de construction pour le code d’interopérabilité, mais l’absence de prise en charge dans les génériques rend impossible la création de routines réutilisables dans tous les types non managés.Unmanaged types are one of the core building blocks for interop code, yet the lack of support in generics makes it impossible to create re-usable routines across all unmanaged types. Au lieu de cela, les développeurs sont obligés de créer le même code de plaque de chaudière pour chaque type non géré dans leur bibliothèque :Instead developers are forced to author the same boiler plate code for every unmanaged type in their library:

int Hash(Point point) { ... } 
int Hash(TimeSpan timeSpan) { ... } 

Pour activer ce type de scénario, le langage introduira une nouvelle contrainte : non géré :To enable this type of scenario the language will be introducing a new constraint: unmanaged:

void Hash<T>(T value) where T : unmanaged
{
    ...
}

Cette contrainte ne peut être satisfaite que par les types qui s’intègrent à la définition de type non managé dans la spécification du langage C#. Une autre façon de le regarder est qu’un type répond à la contrainte non managée s’il peut également être utilisé comme pointeur.This constraint can only be met by types which fit into the unmanaged type definition in the C# language spec. Another way of looking at it is that a type satisfies the unmanaged constraint if it can also be used as a pointer.

Hash(new Point()); // Okay 
Hash(42); // Okay
Hash("hello") // Error: Type string does not satisfy the unmanaged constraint

Les paramètres de type avec la contrainte non managée peuvent utiliser toutes les fonctionnalités disponibles pour les types non managés : pointeurs, fixe, etc.Type parameters with the unmanaged constraint can use all the features available to unmanaged types: pointers, fixed, etc ...

void Hash<T>(T value) where T : unmanaged
{
    // Okay
    fixed (T* p = &value) 
    { 
        ...
    }
}

Cette contrainte permettra également d’effectuer des conversions efficaces entre les données structurées et les flux d’octets.This constraint will also make it possible to have efficient conversions between structured data and streams of bytes. Il s’agit d’une opération qui est courante dans les piles de mise en réseau et les couches de sérialisation :This is an operation that is common in networking stacks and serialization layers:

Span<byte> Convert<T>(ref T value) where T : unmanaged 
{
    ...
}

Ces routines sont avantageuses, car elles sont prouvées de manière prouvée au moment de la compilation et à l’allocation gratuite.Such routines are advantageous because they are provably safe at compile time and allocation free. Aujourd’hui, les auteurs d’interopérabilité ne peuvent pas effectuer cette opération (même si elles se trouvent dans une couche où les performances sont critiques).Interop authors today can not do this (even though it's at a layer where perf is critical). Au lieu de cela, ils doivent s’appuyer sur l’allocation de routines qui ont des vérifications d’exécution coûteuses pour vérifier que les valeurs sont correctement non gérées.Instead they need to rely on allocating routines that have expensive runtime checks to verify values are correctly unmanaged.

Conception détailléeDetailed design

La langue introduira une nouvelle contrainte nommée unmanaged .The language will introduce a new constraint named unmanaged. Pour satisfaire cette contrainte, un type doit être un struct et tous les champs du type doivent appartenir à l’une des catégories suivantes :In order to satisfy this constraint a type must be a struct and all the fields of the type must fall into one of the following categories:

  • Ont le type sbyte , byte , short , ushort , int , uint , long , ulong , char , float , double , decimal , bool IntPtr ou UIntPtr .Have the type sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, IntPtr or UIntPtr.
  • Être de n’importe quel enum type.Be any enum type.
  • Être un type pointeur.Be a pointer type.
  • Il s’agit d’un struct défini par l’utilisateur qui satisfait la unmanaged contrainte.Be a user defined struct that satisfies the unmanaged constraint.

Les champs d’instance générés par le compilateur, tels que les propriétés implémentées automatiquement, doivent également respecter ces contraintes.Compiler generated instance fields, such as those backing auto-implemented properties, must also meet these constraints.

Par exemple :For example:

// Unmanaged type
struct Point 
{ 
    int X;
    int Y {get; set;}
}

// Not an unmanaged type
struct Student 
{ 
    string FirstName;
    string LastName;
}

La unmanaged contrainte ne peut pas être combinée avec struct , class ou new() .The unmanaged constraint cannot be combined with struct, class or new(). Cette restriction dérive du fait qu' unmanaged implique que struct les autres contraintes n’ont pas de sens.This restriction derives from the fact that unmanaged implies struct hence the other constraints do not make sense.

La unmanaged contrainte n’est pas appliquée par le CLR, uniquement par le langage.The unmanaged constraint is not enforced by CLR, only by the language. Pour empêcher la mauvaise utilisation par d’autres langages, les méthodes qui ont cette contrainte sont protégées par une demande mod-req. Cela empêchera d’autres langages d’utiliser des arguments de type qui ne sont pas des types non managés.To prevent mis-use by other languages, methods which have this constraint will be protected by a mod-req. This will prevent other languages from using type arguments which are not unmanaged types.

Le jeton unmanaged de la contrainte n’est pas un mot clé, ni un mot clé contextuel.The token unmanaged in the constraint is not a keyword, nor a contextual keyword. Au lieu de cela, il est similaire au fait qu' var il est évalué à cet emplacement et que :Instead it is like var in that it is evaluated at that location and will either:

  • Liaison à un type défini par l’utilisateur ou à un type référencé nommé unmanaged : cette opération est traitée comme toute autre contrainte de type nommé.Bind to user defined or referenced type named unmanaged: This will be treated just as any other named type constraint is treated.
  • Lier à aucun type : cette valeur sera interprétée comme la unmanaged contrainte.Bind to no type: This will be interpreted as the unmanaged constraint.

Dans le cas où il existe un type nommé unmanaged et qu’il est disponible sans qualification dans le contexte actuel, il n’y aura aucun moyen d’utiliser la unmanaged contrainte.In the case there is a type named unmanaged and it is available without qualification in the current context, then there will be no way to use the unmanaged constraint. Cela correspond aux règles entourant la fonctionnalité var et les types définis par l’utilisateur portant le même nom.This parallels the rules surrounding the feature var and user defined types of the same name.

InconvénientsDrawbacks

Le principal inconvénient de cette fonctionnalité est qu’elle s’occupe d’un petit nombre de développeurs : généralement des auteurs ou des infrastructures de bibliothèque de bas niveau.The primary drawback of this feature is that it serves a small number of developers: typically low level library authors or frameworks. C’est pourquoi le temps de langage est précieux pour un petit nombre de développeurs.Hence it's spending precious language time for a small number of developers.

Toutefois, ces infrastructures sont souvent la base de la majorité des applications .NET.Yet these frameworks are often the basis for the majority of .NET applications out there. Par conséquent, les performances et l’exactitude des victoires à ce niveau peuvent avoir un effet de ondulation sur l’écosystème .NET.Hence performance / correctness wins at this level can have a ripple effect on the .NET ecosystem. Cela rend la fonctionnalité intéressante, même avec le public limité.This makes the feature worth considering even with the limited audience.

Autres solutionsAlternatives

Il existe deux alternatives à prendre en compte :There are a couple of alternatives to consider:

  • État actuel : la fonctionnalité n’est pas justifiée par ses propres avantages et les développeurs continuent d’utiliser le comportement d’adhésion implicite.The status quo: The feature is not justified on its own merits and developers continue to use the implicit opt in behavior.

QuestionsQuestions

Représentation des métadonnéesMetadata Representation

Le langage F # encode la contrainte dans le fichier de signature, ce qui signifie que C# ne peut pas réutiliser sa représentation.The F# language encodes the constraint in the signature file which means C# cannot re-use their representation. Un nouvel attribut doit être choisi pour cette contrainte.A new attribute will need to be chosen for this constraint. En outre, une méthode qui a cette contrainte doit être protégée par un mod-req.Additionally a method which has this constraint must be protected by a mod-req.

Blittable et non géréBlittable vs. Unmanaged

Le langage F # a une fonctionnalité très similaire qui utilise le mot clé non managé.The F# language has a very similar feature which uses the keyword unmanaged. Le nom blittable provient de l’utilisation de Midori.The blittable name comes from the use in Midori. Souhaiterez peut-être Rechercher la priorité ici et utiliser non managé à la place.May want to look to precedence here and use unmanaged instead.

Résolution Le langage décide d’utiliser le non géréResolution The language decide to use unmanaged

VérificateurVerifier

Le vérificateur/Runtime doit-il être mis à jour pour comprendre l’utilisation de pointeurs vers des paramètres de type générique ?Does the verifier / runtime need to be updated to understand the use of pointers to generic type parameters? Ou peut-il simplement fonctionner en l’absence de modifications ?Or can it simply work as is without changes?

Résolution Aucune modification n’est nécessaire.Resolution No changes needed. Tous les types de pointeurs sont simplement non vérifiables.All pointer types are simply unverifiable.

Réunions de conceptionDesign meetings

n/an/a