2 // FieldInfoTest - NUnit Test Cases for the FieldInfo class
5 // Zoltan Varga (vargaz@freemail.hu)
6 // Gert Driesen (drieseng@users.sourceforge.net)
8 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Threading;
33 using System.Reflection;
35 using System.Reflection.Emit;
37 using System.Runtime.InteropServices;
39 using NUnit.Framework;
41 namespace MonoTests.System.Reflection
43 [StructLayout(LayoutKind.Explicit, Pack = 4, Size = 64)]
50 [StructLayout(LayoutKind.Sequential)]
53 [MarshalAsAttribute(UnmanagedType.Bool)]
56 [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)]
59 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)]
62 [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof (Marshal1), MarshalCookie="5")]
65 [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Marshal1), MarshalCookie = "5")]
72 public class Class3 : Class2
77 public class FieldInfoTest
83 public void IsDefined_AttributeType_Null ()
85 Type type = typeof (FieldInfoTest);
86 FieldInfo field = type.GetField ("i");
89 field.IsDefined ((Type) null, false);
91 } catch (ArgumentNullException ex) {
92 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
93 Assert.IsNull (ex.InnerException, "#3");
94 Assert.IsNotNull (ex.Message, "#4");
95 Assert.IsNotNull (ex.ParamName, "#5");
96 Assert.AreEqual ("attributeType", ex.ParamName, "#6");
101 public void GetCustomAttributes ()
106 fi = typeof (Class2).GetField ("f5");
108 attrs = fi.GetCustomAttributes (false);
109 Assert.AreEqual (1, attrs.Length, "#B1");
110 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#B2");
111 attrs = fi.GetCustomAttributes (true);
112 Assert.AreEqual (1, attrs.Length, "#B3");
113 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#B4");
114 attrs = fi.GetCustomAttributes (typeof (MarshalAsAttribute), false);
115 Assert.AreEqual (0, attrs.Length, "#B5");
116 attrs = fi.GetCustomAttributes (typeof (MarshalAsAttribute), true);
117 Assert.AreEqual (0, attrs.Length, "#B6");
118 attrs = fi.GetCustomAttributes (typeof (ObsoleteAttribute), false);
119 Assert.AreEqual (1, attrs.Length, "#B7");
120 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#B8");
121 attrs = fi.GetCustomAttributes (typeof (ObsoleteAttribute), true);
122 Assert.AreEqual (1, attrs.Length, "#B9");
123 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#B10");
125 fi = typeof (Class3).GetField ("f5");
127 attrs = fi.GetCustomAttributes (false);
128 Assert.AreEqual (1, attrs.Length, "#D1");
129 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#D2");
130 attrs = fi.GetCustomAttributes (true);
131 Assert.AreEqual (1, attrs.Length, "#D3");
132 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#D4");
133 attrs = fi.GetCustomAttributes (typeof (MarshalAsAttribute), false);
134 Assert.AreEqual (0, attrs.Length, "#D5");
135 attrs = fi.GetCustomAttributes (typeof (MarshalAsAttribute), true);
136 Assert.AreEqual (0, attrs.Length, "#D6");
137 attrs = fi.GetCustomAttributes (typeof (ObsoleteAttribute), false);
138 Assert.AreEqual (1, attrs.Length, "#D7");
139 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#D8");
140 attrs = fi.GetCustomAttributes (typeof (ObsoleteAttribute), true);
141 Assert.AreEqual (1, attrs.Length, "#D9");
142 Assert.AreEqual (typeof (ObsoleteAttribute), attrs [0].GetType (), "#D10");
145 [Test] // GetFieldFromHandle (RuntimeFieldHandle)
146 public void GetFieldFromHandle1_Handle_Zero ()
148 RuntimeFieldHandle fh = new RuntimeFieldHandle ();
151 FieldInfo.GetFieldFromHandle (fh);
153 } catch (ArgumentException ex) {
154 // Handle is not initialized
155 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
156 Assert.IsNull (ex.InnerException, "#3");
157 Assert.IsNotNull (ex.Message, "#4");
158 Assert.IsNull (ex.ParamName, "#5");
163 [Test] // GetFieldFromHandle (RuntimeFieldHandle, RuntimeTypeHandle)
164 public void GetFieldFromHandle2_DeclaringType_Zero ()
166 RuntimeTypeHandle th = new RuntimeTypeHandle ();
167 FieldInfo fi1 = typeof (Class2).GetField ("f5");
168 RuntimeFieldHandle fh = fi1.FieldHandle;
170 FieldInfo fi2 = FieldInfo.GetFieldFromHandle (fh, th);
171 Assert.IsNotNull (fi2, "#1");
172 Assert.AreSame (fi1.DeclaringType, fi2.DeclaringType, "#2");
173 Assert.AreEqual (fi1.FieldType, fi2.FieldType, "#3");
174 Assert.AreEqual (fi1.Name, fi2.Name, "#4");
177 [Test] // GetFieldFromHandle (RuntimeFieldHandle, RuntimeTypeHandle)
178 public void GetFieldFromHandle2_Handle_Generic ()
180 FieldInfoTest<string> instance = new FieldInfoTest<string> ();
181 Type t = instance.GetType ();
183 FieldInfo fi1 = t.GetField ("TestField");
184 RuntimeFieldHandle fh = fi1.FieldHandle;
185 RuntimeTypeHandle th = t.TypeHandle;
187 FieldInfo fi2 = FieldInfo.GetFieldFromHandle (fh, th);
188 Assert.IsNotNull (fi2, "#1");
189 Assert.AreSame (t, fi2.DeclaringType, "#2");
190 Assert.AreEqual (typeof (string), fi2.FieldType, "#3");
191 Assert.AreEqual ("TestField", fi2.Name, "#4");
194 [Test] // GetFieldFromHandle (RuntimeFieldHandle, RuntimeTypeHandle)
195 [Category ("NotWorking")]
196 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=343449
197 public void GetFieldFromHandle2_Handle_GenericDefinition ()
199 Type t1 = typeof (FieldInfoTest<>);
200 FieldInfo fi1 = t1.GetField ("TestField");
201 RuntimeFieldHandle fh = fi1.FieldHandle;
203 FieldInfoTest<string> instance = new FieldInfoTest<string> ();
204 Type t2 = instance.GetType ();
205 RuntimeTypeHandle th = t2.TypeHandle;
207 FieldInfo fi2 = FieldInfo.GetFieldFromHandle (fh, th);
208 Assert.IsNotNull (fi2, "#1");
209 Assert.AreSame (t2, fi2.DeclaringType, "#2");
210 Assert.AreEqual (typeof (string), fi2.FieldType, "#3");
211 Assert.AreEqual ("TestField", fi2.Name, "#4");
214 [Test] // GetFieldFromHandle (RuntimeFieldHandle, RuntimeTypeHandle)
215 public void GetFieldFromHandle2_Handle_Zero ()
217 object instance = new Class2 ();
218 RuntimeTypeHandle th = Type.GetTypeHandle (instance);
219 RuntimeFieldHandle fh = new RuntimeFieldHandle ();
222 FieldInfo.GetFieldFromHandle (fh, th);
224 } catch (ArgumentException ex) {
225 // Handle is not initialized
226 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
227 Assert.IsNull (ex.InnerException, "#3");
228 Assert.IsNotNull (ex.Message, "#4");
229 Assert.IsNull (ex.ParamName, "#5");
235 public void PseudoCustomAttributes ()
238 Type t = typeof (FieldInfoTest);
241 Assert.AreEqual (1, t.GetField ("i").GetCustomAttributes (typeof (NonSerializedAttribute), true).Length);
243 Assert.AreEqual (0, t.GetField ("i").GetCustomAttributes (typeof (NonSerializedAttribute), true).Length);
246 attrs = typeof (Class1).GetField ("i").GetCustomAttributes (true);
248 Assert.AreEqual (1, attrs.Length, "#B1");
249 FieldOffsetAttribute field_attr = (FieldOffsetAttribute) attrs [0];
250 Assert.AreEqual (32, field_attr.Value, "#B2");
252 Assert.AreEqual (0, attrs.Length, "#B1");
255 MarshalAsAttribute attr;
257 attrs = typeof (Class2).GetField ("f0").GetCustomAttributes (true);
259 Assert.AreEqual (1, attrs.Length, "#C1");
260 attr = (MarshalAsAttribute) attrs [0];
261 Assert.AreEqual (UnmanagedType.Bool, attr.Value, "#C2");
263 Assert.AreEqual (0, attrs.Length, "#C1");
266 attrs = typeof (Class2).GetField ("f1").GetCustomAttributes (true);
268 Assert.AreEqual (1, attrs.Length, "#D1");
269 attr = (MarshalAsAttribute) attrs [0];
270 Assert.AreEqual (UnmanagedType.LPArray, attr.Value, "#D2");
271 Assert.AreEqual (UnmanagedType.LPStr, attr.ArraySubType, "#D3");
273 Assert.AreEqual (0, attrs.Length, "#D1");
276 attrs = typeof (Class2).GetField ("f2").GetCustomAttributes (true);
278 Assert.AreEqual (1, attrs.Length, "#E1");
279 attr = (MarshalAsAttribute) attrs [0];
280 Assert.AreEqual (UnmanagedType.ByValTStr, attr.Value, "#E2");
281 Assert.AreEqual (100, attr.SizeConst, "#E3");
283 Assert.AreEqual (0, attrs.Length, "#E1");
286 attrs = typeof (Class2).GetField ("f3").GetCustomAttributes (true);
288 Assert.AreEqual (1, attrs.Length, "#F1");
289 attr = (MarshalAsAttribute) attrs [0];
290 Assert.AreEqual (UnmanagedType.CustomMarshaler, attr.Value, "#F2");
291 Assert.AreEqual ("5", attr.MarshalCookie, "#F3");
292 Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#F4");
294 Assert.AreEqual (0, attrs.Length, "#F1");
297 attrs = typeof (Class3).GetField ("f3").GetCustomAttributes (false);
299 Assert.AreEqual (1, attrs.Length, "#G1");
300 attr = (MarshalAsAttribute) attrs [0];
301 Assert.AreEqual (UnmanagedType.CustomMarshaler, attr.Value, "#G2");
302 Assert.AreEqual ("5", attr.MarshalCookie, "#G3");
303 Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#G4");
305 Assert.AreEqual (0, attrs.Length, "#G1");
308 attrs = typeof (Class3).GetField ("f3").GetCustomAttributes (true);
310 Assert.AreEqual (1, attrs.Length, "#H1");
311 attr = (MarshalAsAttribute) attrs [0];
312 Assert.AreEqual (UnmanagedType.CustomMarshaler, attr.Value, "#H2");
313 Assert.AreEqual ("5", attr.MarshalCookie, "#H3");
314 Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#H4");
316 Assert.AreEqual (0, attrs.Length, "#H1");
320 attrs = typeof (Class2).GetField ("f3").GetCustomAttributes (true);
322 Assert.AreEqual (1, attrs.Length, "#I1");
323 attr = (MarshalAsAttribute) attrs [0];
324 Assert.AreEqual (UnmanagedType.CustomMarshaler, attr.Value, "#I2");
325 Assert.AreEqual ("5", attr.MarshalCookie, "#I3");
326 Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#I4");
328 Assert.AreEqual (0, attrs.Length, "#I1");
333 public static int static_field;
337 [ExpectedException (typeof (ArgumentException))]
338 public void GetValueWrongObject ()
342 typeof (Foo).GetField ("field").GetValue (typeof (int));
345 public void GetValueWrongObjectStatic ()
349 // This is allowed in MS.NET
350 typeof (Foo).GetField ("static_field").GetValue (typeof (int));
354 #if !TARGET_JVM // ReflectionOnlyLoad not supported for TARGET_JVM
356 [ExpectedException (typeof (InvalidOperationException))]
357 public void GetValueOnRefOnlyAssembly ()
359 Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (FieldInfoTest).Assembly.FullName);
360 Type t = assembly.GetType (typeof (RefOnlyFieldClass).FullName);
361 FieldInfo f = t.GetField ("RefOnlyField", BindingFlags.Static | BindingFlags.NonPublic);
366 [ExpectedException (typeof (InvalidOperationException))]
367 public void SetValueOnRefOnlyAssembly ()
369 Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (FieldInfoTest).Assembly.FullName);
370 Type t = assembly.GetType (typeof (RefOnlyFieldClass).FullName);
371 FieldInfo f = t.GetField ("RefOnlyField", BindingFlags.Static | BindingFlags.NonPublic);
372 f.SetValue (null, 8);
376 const int literal = 42;
379 [ExpectedException (typeof (FieldAccessException))]
380 public void SetValueOnLiteralField ()
382 FieldInfo f = typeof (FieldInfoTest).GetField ("literal", BindingFlags.Static | BindingFlags.NonPublic);
383 f.SetValue (null, 0);
386 public int? nullable_field;
388 public static int? static_nullable_field;
391 public void NullableTests ()
393 FieldInfoTest t = new FieldInfoTest ();
395 FieldInfo fi = typeof (FieldInfoTest).GetField ("nullable_field");
397 fi.SetValue (t, 101);
398 Assert.AreEqual (101, fi.GetValue (t));
399 fi.SetValue (t, null);
400 Assert.AreEqual (null, fi.GetValue (t));
402 FieldInfo fi2 = typeof (FieldInfoTest).GetField ("static_nullable_field");
404 fi2.SetValue (t, 101);
405 Assert.AreEqual (101, fi2.GetValue (t));
406 fi2.SetValue (t, null);
407 Assert.AreEqual (null, fi2.GetValue (t));
410 #if !TARGET_JVM // TypeBuilder not supported for TARGET_JVM
412 public void NonPublicTests ()
414 Assembly assembly = Assembly.ReflectionOnlyLoad (typeof (FieldInfoTest).Assembly.FullName);
416 Type t = assembly.GetType (typeof (NonPublicFieldClass).FullName);
418 // try to get non-public field
419 FieldInfo fi = t.GetField ("protectedField");
422 fi = t.GetField ("protectedField", BindingFlags.NonPublic | BindingFlags.Instance);
423 Assert.IsNotNull (fi);
424 // get via typebuilder
425 FieldInfo f = TypeBuilder.GetField (t, fi);
426 Assert.IsNotNull (f);
431 public void GetRawDefaultValue ()
433 Assert.AreEqual (5, typeof (FieldInfoTest).GetField ("int_field").GetRawConstantValue ());
434 Assert.AreEqual (Int64.MaxValue, typeof (FieldInfoTest).GetField ("long_field").GetRawConstantValue ());
435 Assert.AreEqual (2, typeof (FieldInfoTest).GetField ("int_enum_field").GetRawConstantValue ());
436 Assert.AreEqual (typeof (int), typeof (FieldInfoTest).GetField ("int_enum_field").GetRawConstantValue ().GetType ());
437 Assert.AreEqual (2, typeof (FieldInfoTest).GetField ("long_enum_field").GetRawConstantValue ());
438 Assert.AreEqual (typeof (long), typeof (FieldInfoTest).GetField ("long_enum_field").GetRawConstantValue ().GetType ());
439 Assert.AreEqual ("Hello", typeof (FieldInfoTest).GetField ("string_field").GetRawConstantValue ());
440 Assert.AreEqual (null, typeof (FieldInfoTest).GetField ("object_field").GetRawConstantValue ());
444 [ExpectedException (typeof (InvalidOperationException))]
445 public void GetRawDefaultValueNoDefault ()
447 typeof (FieldInfoTest).GetField ("non_const_field").GetRawConstantValue ();
450 public enum IntEnum {
456 public enum LongEnum : long {
462 public const int int_field = 5;
463 public const long long_field = Int64.MaxValue;
464 public const IntEnum int_enum_field = IntEnum.Second;
465 public const LongEnum long_enum_field = LongEnum.Second;
466 public const string string_field = "Hello";
467 public const FieldInfoTest object_field = null;
468 public int non_const_field;
475 class RefOnlyFieldClass
478 static int RefOnlyField;
481 class NonPublicFieldClass
483 protected int protectedField;
486 public class FieldInfoTest<T>