共用方式為


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 存取子的傳回值。

您可以使用 ConstructorMethod來存取建構函式。

比對是藉由比較 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)

適用於