次の方法で共有


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

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

MethodStaticMethodField、および 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)

適用対象