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 主体将引发 MissingFieldExceptionMissingMethodException

自 .NET 9 起支持泛型参数。 泛型参数必须与格式和索引 (的目标匹配,即类型参数必须是类型参数,方法参数必须是方法参数) 。 该方法 extern static 的泛型参数还必须与目标上反映的任何约束完全匹配。 如果约束不匹配,该方法将 InvalidProgramException引发 。

对于 MethodStaticMethodFieldStaticField,批注 extern static 方法的第一个参数的类型标识所属类型。 将仅检查定义的特定类型以查找不可访问的成员。 类型层次结构不会遍地查找匹配项。

第一个参数的值被视为 this 实例字段和方法的指针。

第一个参数必须作为 ref 结构上的实例字段和方法传递。

第一个参数的值不由字段和方法的实现 static 使用,可以是 null

如果需要设置字段,则访问器对字段的返回值可以是 ref

可以使用 或 Method访问Constructor构造函数。

返回类型被视为签名匹配项。 最初不考虑用于签名匹配的 Modreq 和 modopts。 但是,如果存在忽略 modreqs 和 modopts 的歧义性,则会尝试精确匹配。 如果仍存在歧义, 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)

适用于