UnsafeAccessorAttribute Classe

Definizione

Fornisce l'accesso a un membro inaccessibile di un tipo specifico.

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
Ereditarietà
UnsafeAccessorAttribute
Attributi

Esempio

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

Commenti

È possibile applicare questo attributo a un extern static metodo. L'implementazione del extern static metodo annotato con questo attributo verrà fornita dal runtime in base alle informazioni contenute nell'attributo e alla firma del metodo a cui viene applicato l'attributo. Il runtime tenterà di trovare il metodo o il campo corrispondente e inoltrare la chiamata. Se il metodo o il campo corrispondente non viene trovato, il corpo del extern static metodo genererà MissingFieldException o MissingMethodException.

I parametri generici sono supportati da .NET 9. I parametri generici devono corrispondere alla destinazione nel formato e nell'indice, ovvero i parametri di tipo devono essere parametri di tipo e i parametri del metodo devono essere parametri del metodo. Anche extern static i parametri generici del metodo devono corrispondere esattamente a tutti i vincoli riflessi nella destinazione. Se i vincoli non corrispondono, il metodo genera InvalidProgramException.

Per Method, StaticMethod, Fielde StaticField, il tipo del primo argomento del metodo con annotazioni extern static identifica il tipo proprietario. Solo il tipo specifico definito verrà esaminato per i membri inaccessibili. La gerarchia dei tipi non viene esaminata cercando una corrispondenza.

Il valore del primo argomento viene considerato come this puntatore per i campi e i metodi di istanza.

Il primo argomento deve essere passato come ref per i campi e i metodi di istanza negli struct.

Il valore del primo argomento non viene usato dall'implementazione per static i campi e i metodi e può essere null.

Il valore restituito per una funzione di accesso a un campo può essere ref se si desidera impostare il campo.

È possibile accedere ai costruttori usando Constructor o Method.

Il tipo restituito viene considerato per la corrispondenza della firma. Modreqs e modopts inizialmente non vengono considerati per la corrispondenza della firma. Tuttavia, se esiste un'ambiguità ignorando modreqs e modopts, viene tentata una corrispondenza precisa. Se esiste ancora un'ambiguità, AmbiguousMatchException viene generata.

Per impostazione predefinita, il nome del metodo con attributi determina il nome del metodo/campo. Ciò può causare confusione in alcuni casi perché le astrazioni del linguaggio, ad esempio le funzioni locali C#, generano nomi IL mangled. La soluzione a questo scopo consiste nell'usare il nameof meccanismo e definire la Name proprietà .

Costruttori

UnsafeAccessorAttribute(UnsafeAccessorKind)

Crea un'istanza di un UnsafeAccessorAttribute oggetto che fornisce l'accesso a un membro di tipo UnsafeAccessorKind.

Proprietà

Kind

Ottiene il tipo di membro a cui viene fornito l'accesso.

Name

Ottiene o imposta il nome del membro a cui viene fornito l'accesso.

TypeId

Quando è implementata in una classe derivata, ottiene un identificatore univoco della classe Attribute.

(Ereditato da Attribute)

Metodi

Equals(Object)

Restituisce un valore che indica se questa istanza è uguale a un oggetto specificato.

(Ereditato da Attribute)
GetHashCode()

Restituisce il codice hash per l'istanza.

(Ereditato da Attribute)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
IsDefaultAttribute()

In caso di override in una classe derivata, indica se il valore di questa istanza è il valore predefinito per la classe derivata.

(Ereditato da Attribute)
Match(Object)

Quando è sottoposto a override in una classe derivata, restituisce un valore che indica se questa istanza equivale a un oggetto specificato.

(Ereditato da Attribute)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)

Si applica a