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) |
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) |