Udostępnij za pośrednictwem


UnsafeAccessorAttribute Klasa

Definicja

Zapewnia dostęp do niedostępnego elementu członkowskiego określonego typu.

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
Dziedziczenie
UnsafeAccessorAttribute
Atrybuty

Przykłady

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

Uwagi

Ten atrybut można zastosować do metody extern static. Implementacja metody extern static z adnotacją o tym atrybucie zostanie udostępniona przez środowisko uruchomieniowe na podstawie informacji w atrybucie i sygnatury metody, do którego jest stosowany atrybut. Środowisko uruchomieniowe spróbuje znaleźć zgodną metodę lub pole i przekazać do niego wywołanie. Jeśli nie zostanie znaleziona zgodna metoda lub pole, treść metody extern static zgłosi MissingFieldException lub MissingMethodException.

Parametry ogólne są obsługiwane od platformy .NET 9. Parametry ogólne muszą być zgodne z obiektem docelowym w postaci i indeksie (czyli parametry typu muszą być parametrami typu, a parametry metody muszą być parametrami metody). Parametry ogólne metody extern static muszą również dokładnie odpowiadać wszelkim ograniczeniom odzwierciedlonym w obiekcie docelowym. Jeśli ograniczenia nie są zgodne, metoda zgłasza InvalidProgramException.

W przypadku MethodStaticMethod, Fieldi StaticFieldtyp pierwszego argumentu metody z adnotacjami extern static identyfikuje typ własności. Tylko określony typ zdefiniowany zostanie zbadany dla niedostępnych elementów członkowskich. Hierarchia typów nie jest wyszukiwana w poszukiwaniu dopasowania.

Wartość pierwszego argumentu jest traktowana jako wskaźnik this dla pól i metod wystąpień.

Pierwszy argument musi zostać przekazany jako ref dla pól i metod wystąpienia w strukturach.

Wartość pierwszego argumentu nie jest używana przez implementację dla pól i metod static i może być null.

Wartość zwracana dla metody dostępu do pola może być ref, jeśli wymagane jest ustawienie pola.

Dostęp do konstruktorów można uzyskać przy użyciu Constructor lub Method.

Dopasowanie jest określane przez porównanie podpisów metadanych zgodnie z definicją w sekcji II.23.2 ECMA-335. Zwracany typ jest uznawany za zgodny z podpisem. Modreqs i modopts początkowo nie są brane pod uwagę pod kątem dopasowania podpisu. Jeśli jednak istnieje niejednoznaczność ignorując modreqs i modopts, podjęto próbę dokładnego dopasowania. Jeśli nadal istnieje niejednoznaczność, AmbiguousMatchException zostanie zgłoszony.

Domyślnie nazwa metody przypisanej określa nazwę metody/pola. Może to spowodować zamieszanie w niektórych przypadkach, ponieważ abstrakcje języka, takie jak funkcje lokalne języka C#, generują nazwy mangled IL. Rozwiązaniem jest użycie mechanizmu nameof i zdefiniowanie właściwości Name.

Konstruktory

UnsafeAccessorAttribute(UnsafeAccessorKind)

Tworzy wystąpienie UnsafeAccessorAttribute zapewniające dostęp do elementu członkowskiego rodzaju UnsafeAccessorKind.

Właściwości

Kind

Pobiera rodzaj elementu członkowskiego, do którego jest udostępniany dostęp.

Name

Pobiera lub ustawia nazwę elementu członkowskiego, do którego jest udostępniany dostęp.

TypeId

Po zaimplementowaniu w klasie pochodnej pobiera unikatowy identyfikator dla tego Attribute.

(Odziedziczone po Attribute)

Metody

Equals(Object)

Zwraca wartość wskazującą, czy to wystąpienie jest równe określonemu obiektowi.

(Odziedziczone po Attribute)
GetHashCode()

Zwraca kod skrótu dla tego wystąpienia.

(Odziedziczone po Attribute)
GetType()

Pobiera Type bieżącego wystąpienia.

(Odziedziczone po Object)
IsDefaultAttribute()

Po zastąpieniu w klasie pochodnej wskazuje, czy wartość tego wystąpienia jest wartością domyślną dla klasy pochodnej.

(Odziedziczone po Attribute)
Match(Object)

Po zastąpieniu w klasie pochodnej zwraca wartość wskazującą, czy to wystąpienie jest równe określonemu obiektowi.

(Odziedziczone po Attribute)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Object.

(Odziedziczone po Object)
ToString()

Zwraca ciąg reprezentujący bieżący obiekt.

(Odziedziczone po Object)

Dotyczy