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本体は または MissingMethodExceptionをスローMissingFieldExceptionします。

.NET 9 以降では、ジェネリック パラメーターがサポートされています。 ジェネリック パラメーターは、フォームとインデックスのターゲットと一致する必要があります (つまり、型パラメーターは型パラメーターである必要があり、メソッド パラメーターはメソッド パラメーターである必要があります)。 メソッドのジェネリック パラメーターは extern static 、ターゲットに反映される制約とも完全に一致する必要があります。 制約が一致しない場合、 メソッドは をスローします InvalidProgramException

、、、および StaticFieldの場合Method、注釈付きextern staticメソッドの最初の引数の型は、所有する型を識別FieldStaticMethodします。 定義されている特定の型のみが、アクセスできないメンバーについて調べられます。 型階層は、一致するものを探して歩いていません。

最初の引数の値は、インスタンス フィールドとメソッドのポインターとして 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)

適用対象