Partager via


UnsafeAccessorAttribute Classe

Définition

Fournit l’accès à un membre inaccessible d’un type spécifique.

public ref class UnsafeAccessorAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
public sealed class UnsafeAccessorAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)>]
type UnsafeAccessorAttribute = class
    inherit Attribute
Public NotInheritable Class UnsafeAccessorAttribute
Inherits Attribute
Héritage
UnsafeAccessorAttribute
Attributs

Exemples

public class Class
{
    static void StaticPrivateMethod() { }
    static int StaticPrivateField;
    Class(int i) { PrivateField = i; }
    void PrivateMethod() { }
    int PrivateField;
    int PrivateProperty { get => PrivateField; }
}

public void CallStaticPrivateMethod()
{
    StaticPrivateMethod(null);

    [UnsafeAccessor(UnsafeAccessorKind.StaticMethod, Name = nameof(StaticPrivateMethod))]
    extern static void StaticPrivateMethod(Class c);
}
public void GetSetStaticPrivateField()
{
    ref int f = ref GetSetStaticPrivateField(null);

    [UnsafeAccessor(UnsafeAccessorKind.StaticField, Name = "StaticPrivateField")]
    extern static ref int GetSetStaticPrivateField(Class c);
}
public void CallPrivateConstructor()
{
    Class c1 = PrivateCtor(1);

    Class c2 = (Class)RuntimeHelpers.GetUninitializedObject(typeof(Class));

    PrivateCtorAsMethod(c2, 2);

    [UnsafeAccessor(UnsafeAccessorKind.Constructor)]
    extern static Class PrivateCtor(int i);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = ".ctor")]
    extern static void PrivateCtorAsMethod(Class c, int i);

}
public void CallPrivateMethod(Class c)
{
    PrivateMethod(c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(PrivateMethod))]
    extern static void PrivateMethod(Class c);
}
public void GetPrivateProperty(Class c)
{
    int f = GetPrivateProperty(c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_PrivateProperty")]
    extern static int GetPrivateProperty(Class c);
}
public void GetSetPrivateField(Class c)
{
    ref int f = ref GetSetPrivateField(c);

    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "PrivateField")]
    extern static ref int GetSetPrivateField(Class c);
}

// Generic example
public class Class<T>
{
    private T _field;
    private void M(T t) { }
    private void GM<U>(U u) { }
    private void GMWithConstraints<U, V>(U u, V v) where U : V, IEquatable<U> { }
}

class Accessors<V>
{
    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_field")]
    public extern static ref V GetSetPrivateField(Class<V> c);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "M")]
    public extern static void CallM(Class<V> c, V v);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "GM")]
    public extern static void CallGM<X>(Class<V> c, X x);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "GMWithConstraints")]
    public extern static void CallGMWithConstraints<X, Y>(Class<V> c, X x, Y y) where X : Y, IEquatable<X>;
}

public void AccessGenericType(Class<int> c)
{
    ref int f = ref Accessors<int>.GetSetPrivateField(c);

    Accessors<int>.CallM(c, 1);

    Accessors<int>.CallGM<string>(c, string.Empty);

    Accessors<int>.CallGMWithConstraints<string, object>(c, string.Empty, new object());
}

Remarques

Vous pouvez appliquer cet attribut à une méthode extern static. L’implémentation de la méthode extern static annotée avec cet attribut est fournie par le runtime en fonction des informations contenues dans l’attribut et de la signature de la méthode à laquelle l’attribut est appliqué. Le runtime essaiera de trouver la méthode ou le champ correspondant et de transférer l’appel à celui-ci. Si la méthode ou le champ correspondant n’est pas trouvé, le corps de la méthode extern static lève MissingFieldException ou MissingMethodException.

Les paramètres génériques sont pris en charge depuis .NET 9. Les paramètres génériques doivent correspondre à la cible sous forme et à l’index (autrement dit, les paramètres de type doivent être des paramètres de type et les paramètres de méthode doivent être des paramètres de méthode). Les paramètres génériques de la méthode extern static doivent également correspondre exactement aux contraintes reflétées sur la cible. Si les contraintes ne correspondent pas, la méthode lève InvalidProgramException.

Pour Method, StaticMethod, Fieldet StaticField, le type du premier argument de la méthode extern static annotée identifie le type propriétaire. Seul le type spécifique défini sera examiné pour les membres inaccessibles. La hiérarchie de types n’est pas parcourue à la recherche d’une correspondance.

La valeur du premier argument est traitée comme pointeur this pour les champs et méthodes d’instance.

Le premier argument doit être passé en tant que ref pour les champs et méthodes d’instance sur les structs.

La valeur du premier argument n’est pas utilisée par l’implémentation pour static champs et méthodes et peut être null.

La valeur de retour d’un accesseur à un champ peut être ref si la définition du champ est souhaitée.

Les constructeurs sont accessibles à l’aide de Constructor ou de Method.

Une correspondance est déterminée en comparant les signatures de métadonnées définies dans la section II.23.2 de ECMA-335. Le type de retour est pris en compte pour la correspondance de signature. Les modreqs et les modopts ne sont initialement pas pris en compte pour la correspondance de signature. Toutefois, si une ambiguïté existe en ignorant les modreqs et les modopts, une correspondance précise est tentée. Si une ambiguïté existe toujours, AmbiguousMatchException est levée.

Par défaut, le nom de la méthode attribuée détermine le nom de la méthode/champ. Cela peut entraîner une confusion dans certains cas, car les abstractions de langage, telles que les fonctions locales C#, génèrent des noms IL bascules. La solution à ceci consiste à utiliser le mécanisme de nameof et à définir la propriété Name.

Constructeurs

UnsafeAccessorAttribute(UnsafeAccessorKind)

Instancie un UnsafeAccessorAttribute fournissant l’accès à un membre de type UnsafeAccessorKind.

Propriétés

Kind

Obtient le type de membre auquel l’accès est fourni.

Name

Obtient ou définit le nom du membre auquel l’accès est fourni.

TypeId

En cas d’implémentation dans une classe dérivée, obtient un identificateur unique pour cette Attribute.

(Hérité de Attribute)

Méthodes

Equals(Object)

Retourne une valeur qui indique si cette instance est égale à un objet spécifié.

(Hérité de Attribute)
GetHashCode()

Retourne le code de hachage pour cette instance.

(Hérité de Attribute)
GetType()

Obtient la Type de l’instance actuelle.

(Hérité de Object)
IsDefaultAttribute()

En cas de substitution dans une classe dérivée, indique si la valeur de cette instance est la valeur par défaut de la classe dérivée.

(Hérité de Attribute)
Match(Object)

En cas de substitution dans une classe dérivée, retourne une valeur qui indique si cette instance est égale à un objet spécifié.

(Hérité de Attribute)
MemberwiseClone()

Crée une copie superficielle du Objectactuel.

(Hérité de Object)
ToString()

Retourne une chaîne qui représente l’objet actuel.

(Hérité de Object)

S’applique à