UnsafeAccessorAttribute 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供对特定类型的不可访问成员的访问权限。
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
- 继承
- 属性
示例
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访问构造函数。
匹配通过比较 ECMA-335第 II.23.2 节中定义的元数据签名来确定。 返回类型被视为签名匹配项。 最初不考虑 Modreqs 和 modopts 进行签名匹配。 但是,如果存在不明确性忽略 modreqs 和 modopts,则会尝试精确匹配。 如果仍存在歧义,则会引发 AmbiguousMatchException。
默认情况下,特性化方法的名称决定了方法/字段的名称。 在某些情况下,这可能会导致混淆,因为语言抽象(如 C# 本地函数)会生成杂乱的 IL 名称。 解决方法是使用 nameof
机制并定义 Name 属性。
构造函数
UnsafeAccessorAttribute(UnsafeAccessorKind) |
实例化提供对类型 UnsafeAccessorKind成员的访问权限的 UnsafeAccessorAttribute。 |
属性
Kind |
获取向其提供访问权限的成员类型。 |
Name |
获取或设置提供访问权限的成员的名称。 |
TypeId |
在派生类中实现时,获取此 Attribute的唯一标识符。 (继承自 Attribute) |
方法
Equals(Object) |
返回一个值,该值指示此实例是否等于指定对象。 (继承自 Attribute) |
GetHashCode() |
返回此实例的哈希代码。 (继承自 Attribute) |
GetType() |
获取当前实例的 Type。 (继承自 Object) |
IsDefaultAttribute() |
在派生类中重写时,指示此实例的值是否为派生类的默认值。 (继承自 Attribute) |
Match(Object) |
在派生类中重写时,返回一个值,该值指示此实例是否等于指定对象。 (继承自 Attribute) |
MemberwiseClone() |
创建当前 Object的浅表副本。 (继承自 Object) |
ToString() |
返回一个表示当前对象的字符串。 (继承自 Object) |