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) |
具現化 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) |