反射-如何将程序集加载到仅反射上下文中
1只反射加载上下文使您能够检查为其他平台或 .NET Framework 的其他版本编译的程序集。加载到此上下文中的代码只能检查,不能执行。这意味着无法创建对象,因为无法执行构造函数。因为该代码无法执行,所以不会自动加载依赖项。如果需要对依赖项进行检查,则必须自行加载。
2
3将程序集加载到只反射加载上下文中
4使用 ReflectionOnlyLoad(String) 方法重载可加载给定了显示名称的程序集,而使用 ReflectionOnlyLoadFrom 方法可加载给定了路径的程序集。如果该程序集为二进制文件映像,则使用 ReflectionOnlyLoad(array<Byte>[]()[]) 方法重载。
5
6注意:
7您不能使用只反射上下文从非执行上下文中的 .NET Framework 版本加载 mscorlib.dll 版本。
8
9
10如果该程序集具有依赖项,ReflectionOnlyLoad 方法不会加载这些依赖项。如果需要对依赖项进行检查,则必须自行加载。
11
12使用程序集的 ReflectionOnly 属性确定是否将该程序集加载到了只反射上下文中。
13
14如果向该程序集或程序集中的类型应用了属性,则应通过使用 CustomAttributeData 类检查这些属性,以确保未尝试在只反射上下文中执行代码。使用 CustomAttributeData..::.GetCustomAttributes 方法的适当重载可获取表示应用于程序集、成员、模块或参数的属性的 CustomAttributeData 对象。
15
16注意:
17应用于该程序集或其内容的属性可能是在该程序集中定义的,也可能是在加载到只反射上下文中的另一个程序集中定义的。无法事先知道这些属性是在何处定义的。
18
19
20示例
21下面的代码示例演示如何检查应用于加载到只反射上下文中的程序集的属性。
22
23该代码示例定义了一个带有两个构造函数和一个属性 (Property) 的自定义属性 (Attribute)。该属性可应用于程序集、在该程序集中声明的类型、该类型的方法以及该方法的参数。在执行时,该程序集将其本身加载到只反射上下文中,并显示应用到它及它包含的类型和成员的自定义属性的有关信息。
24
25注意:
26为简化该代码示例,该程序集自行完成加载和检查操作。通常情况下,不要在执行上下文和只反射上下文中加载同一程序集。
27
28
29Visual Basic 复制代码
30Imports System
31Imports System.Reflection
32Imports System.Collections.Generic
33Imports System.Collections.ObjectModel
34
35' The example attribute is applied to the assembly.
36<Assembly:Example(ExampleKind.ThirdKind, Note:="This is a note on the assembly.")>
37
38' An enumeration used by the ExampleAttribute class.
39Public Enum ExampleKind
40 FirstKind
41 SecondKind
42 ThirdKind
43 FourthKind
44End Enum
45
46' An example attribute. The attribute can be applied to all
47' targets, from assemblies to parameters.
48'
49<AttributeUsage(AttributeTargets.All)> _
50Public Class ExampleAttribute
51 Inherits Attribute
52
53 ' Data for properties.
54 Private kindValue As ExampleKind
55 Private noteValue As String
56 Private arrayStrings() As String
57 Private arrayNumbers() As Integer
58
59 ' Constructors. The parameterless constructor (.ctor) calls
60 ' the constructor that specifies ExampleKind and an array of
61 ' strings, and supplies the default values.
62 '
63 Public Sub New(ByVal initKind As ExampleKind, ByVal initStrings() As String)
64 kindValue = initKind
65 arrayStrings = initStrings
66 End Sub
67 Public Sub New(ByVal initKind As ExampleKind)
68 Me.New(initKind, Nothing)
69 End Sub
70 Public Sub New()
71 Me.New(ExampleKind.FirstKind, Nothing)
72 End Sub
73
74 ' Properties. The Note and Numbers properties must be read/write, so they
75 ' can be used as named parameters.
76 '
77 Public ReadOnly Property Kind As ExampleKind
78 Get
79 Return kindValue
80 End Get
81 End Property
82 Public ReadOnly Property Strings As String()
83 Get
84 Return arrayStrings
85 End Get
86 End Property
87 Public Property Note As String
88 Get
89 Return noteValue
90 End Get
91 Set
92 noteValue = value
93 End Set
94 End Property
95 Public Property Numbers As Integer()
96 Get
97 Return arrayNumbers
98 End Get
99 Set
100 arrayNumbers = value
101 End Set
102 End Property
103End Class
104
105' The example attribute is applied to the test class.
106'
107<Example(ExampleKind.SecondKind, _
108 New String() { "String array argument, line 1", _
109 "String array argument, line 2", _
110 "String array argument, line 3" }, _
111 Note := "This is a note on the class.", _
112 Numbers := New Integer() { 53, 57, 59 })> _
113Public Class Test
114 ' The example attribute is applied to a method, using the
115 ' parameterless constructor and supplying a named argument.
116 ' The attribute is also applied to the method parameter.
117 '
118 <Example(Note:="This is a note on a method.")> _
119 Public Sub TestMethod(<Example()> ByVal arg As Object)
120 End Sub
121
122 ' Sub Main gets objects representing the assembly, the test
123 ' type, the test method, and the method parameter. Custom
124 ' attribute data is displayed for each of these.
125 '
126 Public Shared Sub Main()
127 Dim asm As [Assembly] = Assembly.ReflectionOnlyLoad("source")
128 Dim t As Type = asm.GetType("Test")
129 Dim m As MethodInfo = t.GetMethod("TestMethod")
130 Dim p() As ParameterInfo = m.GetParameters()
131
132 Console.WriteLine(vbCrLf & "Attributes for assembly: {0}", asm)
133 ShowAttributeData(CustomAttributeData.GetCustomAttributes(asm))
134 Console.WriteLine(vbCrLf & "Attributes for type: {0}", t)
135 ShowAttributeData(CustomAttributeData.GetCustomAttributes(t))
136 Console.WriteLine(vbCrLf & "Attributes for member: {0}", m)
137 ShowAttributeData(CustomAttributeData.GetCustomAttributes(m))
138 Console.WriteLine(vbCrLf & "Attributes for parameter: {0}", p)
139 ShowAttributeData(CustomAttributeData.GetCustomAttributes(p(0)))
140 End Sub
141
142 Private Shared Sub ShowAttributeData( _
143 ByVal attributes As IList(Of CustomAttributeData))
144
145 For Each cad As CustomAttributeData _
146 In CType(attributes, IEnumerable(Of CustomAttributeData))
147
148 Console.WriteLine(" {0}", cad)
149 Console.WriteLine(" Constructor: {0}", cad.Constructor)
150
151 Console.WriteLine(" Constructor arguments:")
152 For Each cata As CustomAttributeTypedArgument _
153 In CType(cad.ConstructorArguments, IEnumerable(Of CustomAttributeTypedArgument))
154
155 ShowValueOrArray(cata)
156 Next
157
158 Console.WriteLine(" Named arguments:")
159 For Each cana As CustomAttributeNamedArgument _
160 In CType(cad.NamedArguments, IEnumerable(Of CustomAttributeNamedArgument))
161
162 Console.WriteLine(" MemberInfo: {0}", _
163 cana.MemberInfo)
164 ShowValueOrArray(cana.TypedValue)
165 Next
166 Next
167 End Sub
168
169 Private Shared Sub ShowValueOrArray(ByVal cata As CustomAttributeTypedArgument)
170 If cata.Value.GetType() Is GetType(ReadOnlyCollection(Of CustomAttributeTypedArgument)) Then
171 Console.WriteLine(" Array of {0}:", cata.ArgumentType)
172
173 For Each cataElement As CustomAttributeTypedArgument In cata.Value
174 Console.WriteLine(" Type: {0} Value: {1}", _
175 cataElement.ArgumentType, cataElement.Value)
176 Next
177 Else
178 Console.WriteLine(" Type: {0} Value: {1}", _
179 cata.ArgumentType, cata.Value)
180 End If
181 End Sub
182End Class
183
184' This code example produces output similar to the following:
185'
186'Attributes for assembly: source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
187' [ExampleAttribute((ExampleKind)2, Note = "This is a note on the assembly.")]
188' Constructor: Void .ctor(ExampleKind)
189' Constructor arguments:
190' Type: ExampleKind Value: 2
191' Named arguments:
192' MemberInfo: System.String Note
193' Type: System.String Value: This is a note on the assembly.
194' [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)]
195' Constructor: Void .ctor(Int32)
196' Constructor arguments:
197' Type: System.Int32 Value: 8
198' Named arguments:
199'
200'Attributes for type: Test
201' [ExampleAttribute((ExampleKind)1, new String[3] { "String array argument, line 1", "String array argument, line 2", "String array argument, line 3" }, Note = "This is a note on the class.", Numbers = new Int32[3] { 53, 57, 59 })]
202' Constructor: Void .ctor(ExampleKind, System.String[])
203' Constructor arguments:
204' Type: ExampleKind Value: 1
205' Array of System.String[]:
206' Type: System.String Value: String array argument, line 1
207' Type: System.String Value: String array argument, line 2
208' Type: System.String Value: String array argument, line 3
209' Named arguments:
210' MemberInfo: System.String Note
211' Type: System.String Value: This is a note on the class.
212' MemberInfo: Int32[] Numbers
213' Array of System.Int32[]:
214' Type: System.Int32 Value: 53
215' Type: System.Int32 Value: 57
216' Type: System.Int32 Value: 59
217'
218'Attributes for member: Void TestMethod(System.Object)
219' [ExampleAttribute(Note = "This is a note on a method.")]
220' Constructor: Void .ctor()
221' Constructor arguments:
222' Named arguments:
223' MemberInfo: System.String Note
224' Type: System.String Value: This is a note on a method.
225'
226'Attributes for parameter: System.Object arg
227' [ExampleAttribute()]
228' Constructor: Void .ctor()
229' Constructor arguments:
230' Named arguments:
231
232
233
234C# 复制代码
235using System;
236using System.Reflection;
237using System.Collections.Generic;
238using System.Collections.ObjectModel;
239
240// The example attribute is applied to the assembly.
241[assembly:Example(ExampleKind.ThirdKind, Note="This is a note on the assembly.")]
242
243// An enumeration used by the ExampleAttribute class.
244public enum ExampleKind
245{
246 FirstKind,
247 SecondKind,
248 ThirdKind,
249 FourthKind
250};
251
252// An example attribute. The attribute can be applied to all
253// targets, from assemblies to parameters.
254//
255[AttributeUsage(AttributeTargets.All)]
256public class ExampleAttribute : Attribute
257{
258 // Data for properties.
259 private ExampleKind kindValue;
260 private string noteValue;
261 private string[] arrayStrings;
262 private int[] arrayNumbers;
263
264 // Constructors. The parameterless constructor (.ctor) calls
265 // the constructor that specifies ExampleKind and an array of
266 // strings, and supplies the default values.
267 //
268 public ExampleAttribute(ExampleKind initKind, string[] initStrings)
269 {
270 kindValue = initKind;
271 arrayStrings = initStrings;
272 }
273 public ExampleAttribute(ExampleKind initKind) : this(initKind, null) {}
274 public ExampleAttribute() : this(ExampleKind.FirstKind, null) {}
275
276 // Properties. The Note and Numbers properties must be read/write, so they
277 // can be used as named parameters.
278 //
279 public ExampleKind Kind { get { return kindValue; }}
280 public string[] Strings { get { return arrayStrings; }}
281 public string Note
282 {
283 get { return noteValue; }
284 set { noteValue = value; }
285 }
286 public int[] Numbers
287 {
288 get { return arrayNumbers; }
289 set { arrayNumbers = value; }
290 }
291}
292
293// The example attribute is applied to the test class.
294//
295[Example(ExampleKind.SecondKind,
296 new string[] { "String array argument, line 1",
297 "String array argument, line 2",
298 "String array argument, line 3" },
299 Note="This is a note on the class.",
300 Numbers = new int[] { 53, 57, 59 })]
301public class Test
302{
303 // The example attribute is applied to a method, using the
304 // parameterless constructor and supplying a named argument.
305 // The attribute is also applied to the method parameter.
306 //
307 [Example(Note="This is a note on a method.")]
308 public void TestMethod([Example] object arg) { }
309
310 // Main() gets objects representing the assembly, the test
311 // type, the test method, and the method parameter. Custom
312 // attribute data is displayed for each of these.
313 //
314 public static void Main()
315 {
316 Assembly asm = Assembly.ReflectionOnlyLoad("Source");
317 Type t = asm.GetType("Test");
318 MethodInfo m = t.GetMethod("TestMethod");
319 ParameterInfo[] p = m.GetParameters();
320
321 Console.WriteLine("\r\nAttributes for assembly: {0}", asm);
322 ShowAttributeData(CustomAttributeData.GetCustomAttributes(asm));
323 Console.WriteLine("\r\nAttributes for type: {0}", t);
324 ShowAttributeData(CustomAttributeData.GetCustomAttributes(t));
325 Console.WriteLine("\r\nAttributes for member: {0}", m);
326 ShowAttributeData(CustomAttributeData.GetCustomAttributes(m));
327 Console.WriteLine("\r\nAttributes for parameter: {0}", p);
328 ShowAttributeData(CustomAttributeData.GetCustomAttributes(p[0]));
329 }
330
331 private static void ShowAttributeData(
332 IList<CustomAttributeData> attributes)
333 {
334 foreach( CustomAttributeData cad in attributes )
335 {
336 Console.WriteLine(" {0}", cad);
337 Console.WriteLine(" Constructor: {0}", cad.Constructor);
338
339 Console.WriteLine(" Constructor arguments:");
340 foreach( CustomAttributeTypedArgument cata
341 in cad.ConstructorArguments )
342 {
343 ShowValueOrArray(cata);
344 }
345
346 Console.WriteLine(" Named arguments:");
347 foreach( CustomAttributeNamedArgument cana
348 in cad.NamedArguments )
349 {
350 Console.WriteLine(" MemberInfo: {0}",
351 cana.MemberInfo);
352 ShowValueOrArray(cana.TypedValue);
353 }
354 }
355 }
356
357 private static void ShowValueOrArray(CustomAttributeTypedArgument cata)
358 {
359 if (cata.Value.GetType() == typeof(ReadOnlyCollection<CustomAttributeTypedArgument>))
360 {
361 Console.WriteLine(" Array of {0}:", cata.ArgumentType);
362
363 foreach (CustomAttributeTypedArgument cataElement in
364 (ReadOnlyCollection<CustomAttributeTypedArgument>) cata.Value)
365 {
366 Console.WriteLine(" Type: {0} Value: {1}",
367 cataElement.ArgumentType, cataElement.Value);
368 }
369 }
370 else
371 {
372 Console.WriteLine(" Type: {0} Value: {1}",
373 cata.ArgumentType, cata.Value);
374 }
375 }
376}
377
378/* This code example produces output similar to the following:
379
380Attributes for assembly: source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
381 [ExampleAttribute((ExampleKind)2, Note = "This is a note on the assembly.")]
382 Constructor: Void .ctor(ExampleKind)
383 Constructor arguments:
384 Type: ExampleKind Value: 2
385 Named arguments:
386 MemberInfo: System.String Note
387 Type: System.String Value: This is a note on the assembly.
388 [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)]
389 Constructor: Void .ctor(Int32)
390 Constructor arguments:
391 Type: System.Int32 Value: 8
392 Named arguments:
393
394Attributes for type: Test
395 [ExampleAttribute((ExampleKind)1, new String[3] { "String array argument, line 1", "String array argument, line 2", "String array argument, line 3" }, Note = "This is a note on the class.", Numbers = new Int32[3] { 53, 57, 59 })]
396 Constructor: Void .ctor(ExampleKind, System.String[])
397 Constructor arguments:
398 Type: ExampleKind Value: 1
399 Array of System.String[]:
400 Type: System.String Value: String array argument, line 1
401 Type: System.String Value: String array argument, line 2
402 Type: System.String Value: String array argument, line 3
403 Named arguments:
404 MemberInfo: System.String Note
405 Type: System.String Value: This is a note on the class.
406 MemberInfo: Int32[] Numbers
407 Array of System.Int32[]:
408 Type: System.Int32 Value: 53
409 Type: System.Int32 Value: 57
410 Type: System.Int32 Value: 59
411
412Attributes for member: Void TestMethod(System.Object)
413 [ExampleAttribute(Note = "This is a note on a method.")]
414 Constructor: Void .ctor()
415 Constructor arguments:
416 Named arguments:
417 MemberInfo: System.String Note
418 Type: System.String Value: This is a note on a method.
419
420Attributes for parameter: System.Object arg
421 [ExampleAttribute()]
422 Constructor: Void .ctor()
423 Constructor arguments:
424 Named arguments:
425*/
426
427
428
2
3将程序集加载到只反射加载上下文中
4使用 ReflectionOnlyLoad(String) 方法重载可加载给定了显示名称的程序集,而使用 ReflectionOnlyLoadFrom 方法可加载给定了路径的程序集。如果该程序集为二进制文件映像,则使用 ReflectionOnlyLoad(array<Byte>[]()[]) 方法重载。
5
6注意:
7您不能使用只反射上下文从非执行上下文中的 .NET Framework 版本加载 mscorlib.dll 版本。
8
9
10如果该程序集具有依赖项,ReflectionOnlyLoad 方法不会加载这些依赖项。如果需要对依赖项进行检查,则必须自行加载。
11
12使用程序集的 ReflectionOnly 属性确定是否将该程序集加载到了只反射上下文中。
13
14如果向该程序集或程序集中的类型应用了属性,则应通过使用 CustomAttributeData 类检查这些属性,以确保未尝试在只反射上下文中执行代码。使用 CustomAttributeData..::.GetCustomAttributes 方法的适当重载可获取表示应用于程序集、成员、模块或参数的属性的 CustomAttributeData 对象。
15
16注意:
17应用于该程序集或其内容的属性可能是在该程序集中定义的,也可能是在加载到只反射上下文中的另一个程序集中定义的。无法事先知道这些属性是在何处定义的。
18
19
20示例
21下面的代码示例演示如何检查应用于加载到只反射上下文中的程序集的属性。
22
23该代码示例定义了一个带有两个构造函数和一个属性 (Property) 的自定义属性 (Attribute)。该属性可应用于程序集、在该程序集中声明的类型、该类型的方法以及该方法的参数。在执行时,该程序集将其本身加载到只反射上下文中,并显示应用到它及它包含的类型和成员的自定义属性的有关信息。
24
25注意:
26为简化该代码示例,该程序集自行完成加载和检查操作。通常情况下,不要在执行上下文和只反射上下文中加载同一程序集。
27
28
29Visual Basic 复制代码
30Imports System
31Imports System.Reflection
32Imports System.Collections.Generic
33Imports System.Collections.ObjectModel
34
35' The example attribute is applied to the assembly.
36<Assembly:Example(ExampleKind.ThirdKind, Note:="This is a note on the assembly.")>
37
38' An enumeration used by the ExampleAttribute class.
39Public Enum ExampleKind
40 FirstKind
41 SecondKind
42 ThirdKind
43 FourthKind
44End Enum
45
46' An example attribute. The attribute can be applied to all
47' targets, from assemblies to parameters.
48'
49<AttributeUsage(AttributeTargets.All)> _
50Public Class ExampleAttribute
51 Inherits Attribute
52
53 ' Data for properties.
54 Private kindValue As ExampleKind
55 Private noteValue As String
56 Private arrayStrings() As String
57 Private arrayNumbers() As Integer
58
59 ' Constructors. The parameterless constructor (.ctor) calls
60 ' the constructor that specifies ExampleKind and an array of
61 ' strings, and supplies the default values.
62 '
63 Public Sub New(ByVal initKind As ExampleKind, ByVal initStrings() As String)
64 kindValue = initKind
65 arrayStrings = initStrings
66 End Sub
67 Public Sub New(ByVal initKind As ExampleKind)
68 Me.New(initKind, Nothing)
69 End Sub
70 Public Sub New()
71 Me.New(ExampleKind.FirstKind, Nothing)
72 End Sub
73
74 ' Properties. The Note and Numbers properties must be read/write, so they
75 ' can be used as named parameters.
76 '
77 Public ReadOnly Property Kind As ExampleKind
78 Get
79 Return kindValue
80 End Get
81 End Property
82 Public ReadOnly Property Strings As String()
83 Get
84 Return arrayStrings
85 End Get
86 End Property
87 Public Property Note As String
88 Get
89 Return noteValue
90 End Get
91 Set
92 noteValue = value
93 End Set
94 End Property
95 Public Property Numbers As Integer()
96 Get
97 Return arrayNumbers
98 End Get
99 Set
100 arrayNumbers = value
101 End Set
102 End Property
103End Class
104
105' The example attribute is applied to the test class.
106'
107<Example(ExampleKind.SecondKind, _
108 New String() { "String array argument, line 1", _
109 "String array argument, line 2", _
110 "String array argument, line 3" }, _
111 Note := "This is a note on the class.", _
112 Numbers := New Integer() { 53, 57, 59 })> _
113Public Class Test
114 ' The example attribute is applied to a method, using the
115 ' parameterless constructor and supplying a named argument.
116 ' The attribute is also applied to the method parameter.
117 '
118 <Example(Note:="This is a note on a method.")> _
119 Public Sub TestMethod(<Example()> ByVal arg As Object)
120 End Sub
121
122 ' Sub Main gets objects representing the assembly, the test
123 ' type, the test method, and the method parameter. Custom
124 ' attribute data is displayed for each of these.
125 '
126 Public Shared Sub Main()
127 Dim asm As [Assembly] = Assembly.ReflectionOnlyLoad("source")
128 Dim t As Type = asm.GetType("Test")
129 Dim m As MethodInfo = t.GetMethod("TestMethod")
130 Dim p() As ParameterInfo = m.GetParameters()
131
132 Console.WriteLine(vbCrLf & "Attributes for assembly: {0}", asm)
133 ShowAttributeData(CustomAttributeData.GetCustomAttributes(asm))
134 Console.WriteLine(vbCrLf & "Attributes for type: {0}", t)
135 ShowAttributeData(CustomAttributeData.GetCustomAttributes(t))
136 Console.WriteLine(vbCrLf & "Attributes for member: {0}", m)
137 ShowAttributeData(CustomAttributeData.GetCustomAttributes(m))
138 Console.WriteLine(vbCrLf & "Attributes for parameter: {0}", p)
139 ShowAttributeData(CustomAttributeData.GetCustomAttributes(p(0)))
140 End Sub
141
142 Private Shared Sub ShowAttributeData( _
143 ByVal attributes As IList(Of CustomAttributeData))
144
145 For Each cad As CustomAttributeData _
146 In CType(attributes, IEnumerable(Of CustomAttributeData))
147
148 Console.WriteLine(" {0}", cad)
149 Console.WriteLine(" Constructor: {0}", cad.Constructor)
150
151 Console.WriteLine(" Constructor arguments:")
152 For Each cata As CustomAttributeTypedArgument _
153 In CType(cad.ConstructorArguments, IEnumerable(Of CustomAttributeTypedArgument))
154
155 ShowValueOrArray(cata)
156 Next
157
158 Console.WriteLine(" Named arguments:")
159 For Each cana As CustomAttributeNamedArgument _
160 In CType(cad.NamedArguments, IEnumerable(Of CustomAttributeNamedArgument))
161
162 Console.WriteLine(" MemberInfo: {0}", _
163 cana.MemberInfo)
164 ShowValueOrArray(cana.TypedValue)
165 Next
166 Next
167 End Sub
168
169 Private Shared Sub ShowValueOrArray(ByVal cata As CustomAttributeTypedArgument)
170 If cata.Value.GetType() Is GetType(ReadOnlyCollection(Of CustomAttributeTypedArgument)) Then
171 Console.WriteLine(" Array of {0}:", cata.ArgumentType)
172
173 For Each cataElement As CustomAttributeTypedArgument In cata.Value
174 Console.WriteLine(" Type: {0} Value: {1}", _
175 cataElement.ArgumentType, cataElement.Value)
176 Next
177 Else
178 Console.WriteLine(" Type: {0} Value: {1}", _
179 cata.ArgumentType, cata.Value)
180 End If
181 End Sub
182End Class
183
184' This code example produces output similar to the following:
185'
186'Attributes for assembly: source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
187' [ExampleAttribute((ExampleKind)2, Note = "This is a note on the assembly.")]
188' Constructor: Void .ctor(ExampleKind)
189' Constructor arguments:
190' Type: ExampleKind Value: 2
191' Named arguments:
192' MemberInfo: System.String Note
193' Type: System.String Value: This is a note on the assembly.
194' [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)]
195' Constructor: Void .ctor(Int32)
196' Constructor arguments:
197' Type: System.Int32 Value: 8
198' Named arguments:
199'
200'Attributes for type: Test
201' [ExampleAttribute((ExampleKind)1, new String[3] { "String array argument, line 1", "String array argument, line 2", "String array argument, line 3" }, Note = "This is a note on the class.", Numbers = new Int32[3] { 53, 57, 59 })]
202' Constructor: Void .ctor(ExampleKind, System.String[])
203' Constructor arguments:
204' Type: ExampleKind Value: 1
205' Array of System.String[]:
206' Type: System.String Value: String array argument, line 1
207' Type: System.String Value: String array argument, line 2
208' Type: System.String Value: String array argument, line 3
209' Named arguments:
210' MemberInfo: System.String Note
211' Type: System.String Value: This is a note on the class.
212' MemberInfo: Int32[] Numbers
213' Array of System.Int32[]:
214' Type: System.Int32 Value: 53
215' Type: System.Int32 Value: 57
216' Type: System.Int32 Value: 59
217'
218'Attributes for member: Void TestMethod(System.Object)
219' [ExampleAttribute(Note = "This is a note on a method.")]
220' Constructor: Void .ctor()
221' Constructor arguments:
222' Named arguments:
223' MemberInfo: System.String Note
224' Type: System.String Value: This is a note on a method.
225'
226'Attributes for parameter: System.Object arg
227' [ExampleAttribute()]
228' Constructor: Void .ctor()
229' Constructor arguments:
230' Named arguments:
231
232
233
234C# 复制代码
235using System;
236using System.Reflection;
237using System.Collections.Generic;
238using System.Collections.ObjectModel;
239
240// The example attribute is applied to the assembly.
241[assembly:Example(ExampleKind.ThirdKind, Note="This is a note on the assembly.")]
242
243// An enumeration used by the ExampleAttribute class.
244public enum ExampleKind
245{
246 FirstKind,
247 SecondKind,
248 ThirdKind,
249 FourthKind
250};
251
252// An example attribute. The attribute can be applied to all
253// targets, from assemblies to parameters.
254//
255[AttributeUsage(AttributeTargets.All)]
256public class ExampleAttribute : Attribute
257{
258 // Data for properties.
259 private ExampleKind kindValue;
260 private string noteValue;
261 private string[] arrayStrings;
262 private int[] arrayNumbers;
263
264 // Constructors. The parameterless constructor (.ctor) calls
265 // the constructor that specifies ExampleKind and an array of
266 // strings, and supplies the default values.
267 //
268 public ExampleAttribute(ExampleKind initKind, string[] initStrings)
269 {
270 kindValue = initKind;
271 arrayStrings = initStrings;
272 }
273 public ExampleAttribute(ExampleKind initKind) : this(initKind, null) {}
274 public ExampleAttribute() : this(ExampleKind.FirstKind, null) {}
275
276 // Properties. The Note and Numbers properties must be read/write, so they
277 // can be used as named parameters.
278 //
279 public ExampleKind Kind { get { return kindValue; }}
280 public string[] Strings { get { return arrayStrings; }}
281 public string Note
282 {
283 get { return noteValue; }
284 set { noteValue = value; }
285 }
286 public int[] Numbers
287 {
288 get { return arrayNumbers; }
289 set { arrayNumbers = value; }
290 }
291}
292
293// The example attribute is applied to the test class.
294//
295[Example(ExampleKind.SecondKind,
296 new string[] { "String array argument, line 1",
297 "String array argument, line 2",
298 "String array argument, line 3" },
299 Note="This is a note on the class.",
300 Numbers = new int[] { 53, 57, 59 })]
301public class Test
302{
303 // The example attribute is applied to a method, using the
304 // parameterless constructor and supplying a named argument.
305 // The attribute is also applied to the method parameter.
306 //
307 [Example(Note="This is a note on a method.")]
308 public void TestMethod([Example] object arg) { }
309
310 // Main() gets objects representing the assembly, the test
311 // type, the test method, and the method parameter. Custom
312 // attribute data is displayed for each of these.
313 //
314 public static void Main()
315 {
316 Assembly asm = Assembly.ReflectionOnlyLoad("Source");
317 Type t = asm.GetType("Test");
318 MethodInfo m = t.GetMethod("TestMethod");
319 ParameterInfo[] p = m.GetParameters();
320
321 Console.WriteLine("\r\nAttributes for assembly: {0}", asm);
322 ShowAttributeData(CustomAttributeData.GetCustomAttributes(asm));
323 Console.WriteLine("\r\nAttributes for type: {0}", t);
324 ShowAttributeData(CustomAttributeData.GetCustomAttributes(t));
325 Console.WriteLine("\r\nAttributes for member: {0}", m);
326 ShowAttributeData(CustomAttributeData.GetCustomAttributes(m));
327 Console.WriteLine("\r\nAttributes for parameter: {0}", p);
328 ShowAttributeData(CustomAttributeData.GetCustomAttributes(p[0]));
329 }
330
331 private static void ShowAttributeData(
332 IList<CustomAttributeData> attributes)
333 {
334 foreach( CustomAttributeData cad in attributes )
335 {
336 Console.WriteLine(" {0}", cad);
337 Console.WriteLine(" Constructor: {0}", cad.Constructor);
338
339 Console.WriteLine(" Constructor arguments:");
340 foreach( CustomAttributeTypedArgument cata
341 in cad.ConstructorArguments )
342 {
343 ShowValueOrArray(cata);
344 }
345
346 Console.WriteLine(" Named arguments:");
347 foreach( CustomAttributeNamedArgument cana
348 in cad.NamedArguments )
349 {
350 Console.WriteLine(" MemberInfo: {0}",
351 cana.MemberInfo);
352 ShowValueOrArray(cana.TypedValue);
353 }
354 }
355 }
356
357 private static void ShowValueOrArray(CustomAttributeTypedArgument cata)
358 {
359 if (cata.Value.GetType() == typeof(ReadOnlyCollection<CustomAttributeTypedArgument>))
360 {
361 Console.WriteLine(" Array of {0}:", cata.ArgumentType);
362
363 foreach (CustomAttributeTypedArgument cataElement in
364 (ReadOnlyCollection<CustomAttributeTypedArgument>) cata.Value)
365 {
366 Console.WriteLine(" Type: {0} Value: {1}",
367 cataElement.ArgumentType, cataElement.Value);
368 }
369 }
370 else
371 {
372 Console.WriteLine(" Type: {0} Value: {1}",
373 cata.ArgumentType, cata.Value);
374 }
375 }
376}
377
378/* This code example produces output similar to the following:
379
380Attributes for assembly: source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
381 [ExampleAttribute((ExampleKind)2, Note = "This is a note on the assembly.")]
382 Constructor: Void .ctor(ExampleKind)
383 Constructor arguments:
384 Type: ExampleKind Value: 2
385 Named arguments:
386 MemberInfo: System.String Note
387 Type: System.String Value: This is a note on the assembly.
388 [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)]
389 Constructor: Void .ctor(Int32)
390 Constructor arguments:
391 Type: System.Int32 Value: 8
392 Named arguments:
393
394Attributes for type: Test
395 [ExampleAttribute((ExampleKind)1, new String[3] { "String array argument, line 1", "String array argument, line 2", "String array argument, line 3" }, Note = "This is a note on the class.", Numbers = new Int32[3] { 53, 57, 59 })]
396 Constructor: Void .ctor(ExampleKind, System.String[])
397 Constructor arguments:
398 Type: ExampleKind Value: 1
399 Array of System.String[]:
400 Type: System.String Value: String array argument, line 1
401 Type: System.String Value: String array argument, line 2
402 Type: System.String Value: String array argument, line 3
403 Named arguments:
404 MemberInfo: System.String Note
405 Type: System.String Value: This is a note on the class.
406 MemberInfo: Int32[] Numbers
407 Array of System.Int32[]:
408 Type: System.Int32 Value: 53
409 Type: System.Int32 Value: 57
410 Type: System.Int32 Value: 59
411
412Attributes for member: Void TestMethod(System.Object)
413 [ExampleAttribute(Note = "This is a note on a method.")]
414 Constructor: Void .ctor()
415 Constructor arguments:
416 Named arguments:
417 MemberInfo: System.String Note
418 Type: System.String Value: This is a note on a method.
419
420Attributes for parameter: System.Object arg
421 [ExampleAttribute()]
422 Constructor: Void .ctor()
423 Constructor arguments:
424 Named arguments:
425*/
426
427
428
这里和大家分享和学习如何学IT!