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建構函式。

傳回型別會視為簽章相符專案。 簽章相符項目一開始不會考慮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)

適用於