Поделиться через


UnsafeAccessorAttribute Класс

Определение

Предоставляет доступ к недоступному элементу определенного типа.

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
Наследование
UnsafeAccessorAttribute
Атрибуты

Примеры

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

Комментарии

Этот атрибут можно применить к методу extern static. Реализация метода extern static, аннотированного с этим атрибутом, будет предоставляться средой выполнения на основе сведений в атрибуте и сигнатуре метода, к которому применяется атрибут. Среда выполнения попытается найти соответствующий метод или поле и перенаправить вызов к нему. Если соответствующий метод или поле не найдено, текст метода extern static вызовет MissingFieldException или MissingMethodException.

Универсальные параметры поддерживаются с .NET 9. Универсальные параметры должны соответствовать целевому объекту в форме и индексе (то есть параметры типа должны быть параметрами типа и параметрами метода должны быть параметрами метода). Универсальные параметры метода extern static также должны точно соответствовать любым ограничениям, отраженным в целевом объекте. Если ограничения не соответствуют, метод создает InvalidProgramException.

Для Method, StaticMethod, Fieldи StaticField, тип первого аргумента аннотированного метода extern static определяет тип владения. Для недоступных членов будет проверяться только определенный тип. Иерархия типов не выполняется поиск совпадения.

Значение первого аргумента рассматривается как указатель this для полей и методов экземпляра.

Первый аргумент должен быть передан как ref для полей экземпляра и методов структур.

Значение первого аргумента не используется реализацией для static полей и методов и может быть null.

Возвращаемое значение для метода доступа к полю может быть ref, если нужно задать поле.

К конструкторам можно обращаться с помощью Constructor или Method.

Совпадение определяется путем сравнения подписей метаданных, определенных в разделе II.23.2 ECMA-335. Возвращаемый тип считается для соответствия сигнатуры. Модрекы и модопты изначально не считаются для совпадения подписей. Однако, если неоднозначность существует, игнорируя модректы и модопты, предпринимается попытка точного совпадения. Если неоднозначность по-прежнему существует, AmbiguousMatchException возникает.

По умолчанию имя метода атрибута определяет имя метода или поля. Это может привести к путанице в некоторых случаях, так как языковые абстракции, такие как локальные функции C#, создают неустранимые имена IL. Решением этого является использование механизма nameof и определение свойства Name.

Конструкторы

UnsafeAccessorAttribute(UnsafeAccessorKind)

Создает экземпляр UnsafeAccessorAttribute предоставления доступа к элементу типа UnsafeAccessorKind.

Свойства

Kind

Получает тип члена, к которому предоставляется доступ.

Name

Возвращает или задает имя члена, к которому предоставляется доступ.

TypeId

При реализации в производном классе получает уникальный идентификатор для этого Attribute.

(Унаследовано от Attribute)

Методы

Equals(Object)

Возвращает значение, указывающее, равен ли этот экземпляр указанному объекту.

(Унаследовано от Attribute)
GetHashCode()

Возвращает хэш-код для этого экземпляра.

(Унаследовано от Attribute)
GetType()

Возвращает Type текущего экземпляра.

(Унаследовано от Object)
IsDefaultAttribute()

При переопределении в производном классе указывает, является ли значение этого экземпляра значением по умолчанию для производного класса.

(Унаследовано от Attribute)
Match(Object)

При переопределении в производном классе возвращает значение, указывающее, равен ли этот экземпляр указанному объекту.

(Унаследовано от Attribute)
MemberwiseClone()

Создает неглубокую копию текущей Object.

(Унаследовано от Object)
ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)

Применяется к