forked from dotnet/dotnet-api-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUnsafeAccessorAttribute.xml
229 lines (197 loc) · 12.8 KB
/
UnsafeAccessorAttribute.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<Type Name="UnsafeAccessorAttribute" FullName="System.Runtime.CompilerServices.UnsafeAccessorAttribute">
<TypeSignature Language="C#" Value="public sealed class UnsafeAccessorAttribute : Attribute" />
<TypeSignature Language="ILAsm" Value=".class public auto ansi sealed beforefieldinit UnsafeAccessorAttribute extends System.Attribute" />
<TypeSignature Language="DocId" Value="T:System.Runtime.CompilerServices.UnsafeAccessorAttribute" />
<TypeSignature Language="VB.NET" Value="Public NotInheritable Class UnsafeAccessorAttribute
Inherits Attribute" />
<TypeSignature Language="F#" Value="type UnsafeAccessorAttribute = class
 inherit Attribute" />
<TypeSignature Language="C++ CLI" Value="public ref class UnsafeAccessorAttribute sealed : Attribute" />
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>8.0.0.0</AssemblyVersion>
<AssemblyVersion>9.0.0.0</AssemblyVersion>
</AssemblyInfo>
<Base>
<BaseTypeName>System.Attribute</BaseTypeName>
</Base>
<Interfaces />
<Attributes>
<Attribute>
<AttributeName Language="C#">[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)]</AttributeName>
<AttributeName Language="F#">[<System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)>]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Runtime.CompilerServices.Nullable(0)]</AttributeName>
<AttributeName Language="F#">[<System.Runtime.CompilerServices.Nullable(0)>]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Runtime.CompilerServices.NullableContext(2)]</AttributeName>
<AttributeName Language="F#">[<System.Runtime.CompilerServices.NullableContext(2)>]</AttributeName>
</Attribute>
</Attributes>
<Docs>
<summary>Provides access to an inaccessible member of a specific type.</summary>
<remarks>
<format type="text/markdown"><. The return type is considered for the signature match. Modreqs and modopts are initially not considered for the signature match. However, if an ambiguity exists ignoring modreqs and modopts, a precise match is attempted. If an ambiguity still exists, <xref:System.Reflection.AmbiguousMatchException> is thrown.
By default, the attributed method's name dictates the name of the method/field. This can cause confusion in some cases since language abstractions, like C# local functions, generate mangled IL names. The solution to this is to use the `nameof` mechanism and define the <xref:System.Runtime.CompilerServices.UnsafeAccessorAttribute.Name> property.
]]></format>
</remarks>
<example>
<code language="csharp">
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());
}
</code>
</example>
</Docs>
<Members>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public UnsafeAccessorAttribute (System.Runtime.CompilerServices.UnsafeAccessorKind kind);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(valuetype System.Runtime.CompilerServices.UnsafeAccessorKind kind) cil managed" />
<MemberSignature Language="DocId" Value="M:System.Runtime.CompilerServices.UnsafeAccessorAttribute.#ctor(System.Runtime.CompilerServices.UnsafeAccessorKind)" />
<MemberSignature Language="VB.NET" Value="Public Sub New (kind As UnsafeAccessorKind)" />
<MemberSignature Language="F#" Value="new System.Runtime.CompilerServices.UnsafeAccessorAttribute : System.Runtime.CompilerServices.UnsafeAccessorKind -> System.Runtime.CompilerServices.UnsafeAccessorAttribute" Usage="new System.Runtime.CompilerServices.UnsafeAccessorAttribute kind" />
<MemberSignature Language="C++ CLI" Value="public:
 UnsafeAccessorAttribute(System::Runtime::CompilerServices::UnsafeAccessorKind kind);" />
<MemberType>Constructor</MemberType>
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>8.0.0.0</AssemblyVersion>
<AssemblyVersion>9.0.0.0</AssemblyVersion>
</AssemblyInfo>
<Parameters>
<Parameter Name="kind" Type="System.Runtime.CompilerServices.UnsafeAccessorKind" />
</Parameters>
<Docs>
<param name="kind">The kind of the target to which access is provided.</param>
<summary>Instantiates an <see cref="T:System.Runtime.CompilerServices.UnsafeAccessorAttribute" /> providing access to a member of kind <see cref="T:System.Runtime.CompilerServices.UnsafeAccessorKind" />.</summary>
<remarks>To be added.</remarks>
</Docs>
</Member>
<Member MemberName="Kind">
<MemberSignature Language="C#" Value="public System.Runtime.CompilerServices.UnsafeAccessorKind Kind { get; }" />
<MemberSignature Language="ILAsm" Value=".property instance valuetype System.Runtime.CompilerServices.UnsafeAccessorKind Kind" />
<MemberSignature Language="DocId" Value="P:System.Runtime.CompilerServices.UnsafeAccessorAttribute.Kind" />
<MemberSignature Language="VB.NET" Value="Public ReadOnly Property Kind As UnsafeAccessorKind" />
<MemberSignature Language="F#" Value="member this.Kind : System.Runtime.CompilerServices.UnsafeAccessorKind" Usage="System.Runtime.CompilerServices.UnsafeAccessorAttribute.Kind" />
<MemberSignature Language="C++ CLI" Value="public:
 property System::Runtime::CompilerServices::UnsafeAccessorKind Kind { System::Runtime::CompilerServices::UnsafeAccessorKind get(); };" />
<MemberType>Property</MemberType>
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>8.0.0.0</AssemblyVersion>
<AssemblyVersion>9.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
<ReturnType>System.Runtime.CompilerServices.UnsafeAccessorKind</ReturnType>
</ReturnValue>
<Docs>
<summary>Gets the kind of member to which access is provided.</summary>
<value>To be added.</value>
<remarks>To be added.</remarks>
</Docs>
</Member>
<Member MemberName="Name">
<MemberSignature Language="C#" Value="public string? Name { get; set; }" />
<MemberSignature Language="ILAsm" Value=".property instance string Name" />
<MemberSignature Language="DocId" Value="P:System.Runtime.CompilerServices.UnsafeAccessorAttribute.Name" />
<MemberSignature Language="VB.NET" Value="Public Property Name As String" />
<MemberSignature Language="F#" Value="member this.Name : string with get, set" Usage="System.Runtime.CompilerServices.UnsafeAccessorAttribute.Name" />
<MemberSignature Language="C++ CLI" Value="public:
 property System::String ^ Name { System::String ^ get(); void set(System::String ^ value); };" />
<MemberType>Property</MemberType>
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>8.0.0.0</AssemblyVersion>
<AssemblyVersion>9.0.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
<ReturnType>System.String</ReturnType>
</ReturnValue>
<Docs>
<summary>Gets or sets the name of the member to which access is provided.</summary>
<value>To be added.</value>
<remarks>The name defaults to the annotated method name if not specified.
The name must be unset/<code>null</code> for <see cref="F:System.Runtime.CompilerServices.UnsafeAccessorKind.Constructor" />.</remarks>
</Docs>
</Member>
</Members>
</Type>