New test.
[mono.git] / mcs / class / corlib / Test / System / TypeTest.cs
1 // TypeTest.cs - NUnit Test Cases for the System.Type class
2 //
3 // Authors:
4 //      Zoltan Varga (vargaz@freemail.hu)
5 //  Patrik Torstensson
6 //
7 // (C) 2003 Ximian, Inc.  http://www.ximian.com
8 // 
9
10 using NUnit.Framework;
11 using System;
12 using System.Collections;
13 using System.IO;
14 using System.Reflection;
15 using System.Runtime.InteropServices;
16
17 class NoNamespaceClass {
18 }
19
20 namespace MonoTests.System
21 {
22         class Super : ICloneable {
23                 public virtual object Clone () {
24                         return null;
25                 }
26         }
27         class Duper: Super {
28         }
29
30         interface IFace1 {
31                 void foo ();
32         }
33
34         interface IFace2 : IFace1 {
35                 void bar ();
36         }
37
38         interface IFace3 : IFace2 {
39         }
40
41         enum TheEnum { A, B, C };
42
43         abstract class Base {
44                 public int level;
45
46                 public abstract int this [byte i] { get; }
47                 public abstract int this [int i] { get; }
48                 public abstract void TestVoid();
49                 public abstract void TestInt(int i);
50         }
51
52         class DeriveVTable : Base {
53                 public override int this [byte i] { get { return 1; } }
54                 public override int this [int i] { get { return 1; } }
55                 public override void TestVoid() { level = 1; }
56                 public override void TestInt(int i) { level = 1; }
57         }
58
59         class NewVTable : DeriveVTable {
60                 public new int this [byte i] { get { return 2; } }
61                 public new int this [int i] { get { return 2; } }
62                 public new void TestVoid() { level = 2; }
63                 public new void TestInt(int i) { level = 2; }
64
65                 public void Overload () { }
66                 public void Overload (int i) { }
67
68                 public NewVTable (out int i) {
69                         i = 0;
70                 }
71
72                 public void byref_method (out int i) {
73                         i = 0;
74                 }
75
76         }
77
78         class Base1 {
79                 public virtual int Foo {
80                         get {
81                                 return 1;
82                         }
83                         set {
84                         }
85                 }
86         }
87
88         class Derived1 : Base1 {
89                 public override int Foo {
90                         set {
91                         }
92                 }
93         }
94
95 #if NET_2_0
96         public class Foo<T> {
97                 public T Whatever;
98         
99                 public T Test {
100                         get { throw new NotImplementedException (); }
101                 }
102
103                 public T Execute(T a) {
104                         return a;
105                 }
106         }
107
108         public interface IBar<T> { }
109         public class Baz<T> : IBar<T> { }
110 #endif
111
112         [TestFixture]
113         public class TypeTest
114         {
115                 private void ByrefMethod (ref int i, ref Derived1 j, ref Base1 k) {
116                 }
117
118                 [Test]
119                 public void TestIsAssignableFrom () {
120                         // Simple tests for inheritance
121                         Assert.AreEqual (typeof (Super).IsAssignableFrom (typeof (Duper)) , true, "#01");
122                         Assert.AreEqual (typeof (Duper).IsAssignableFrom (typeof (Duper)), true, "#02");
123                         Assert.AreEqual (typeof (Object).IsAssignableFrom (typeof (Duper)), true, "#03");
124                         Assert.AreEqual (typeof (ICloneable).IsAssignableFrom (typeof (Duper)), true, "#04");
125
126                         // Tests for arrays
127                         Assert.AreEqual (typeof (Super[]).IsAssignableFrom (typeof (Duper[])), true, "#05");
128                         Assert.AreEqual (typeof (Duper[]).IsAssignableFrom (typeof (Super[])), false, "#06");
129                         Assert.AreEqual (typeof (Object[]).IsAssignableFrom (typeof (Duper[])), true, "#07");
130                         Assert.AreEqual (typeof (ICloneable[]).IsAssignableFrom (typeof (Duper[])), true, "#08");
131
132                         // Tests for multiple dimensional arrays
133                         Assert.AreEqual (typeof (Super[][]).IsAssignableFrom (typeof (Duper[][])), true, "#09");
134                         Assert.AreEqual (typeof (Duper[][]).IsAssignableFrom (typeof (Super[][])), false, "#10");
135                         Assert.AreEqual (typeof (Object[][]).IsAssignableFrom (typeof (Duper[][])), true, "#11");
136                         Assert.AreEqual (typeof (ICloneable[][]).IsAssignableFrom (typeof (Duper[][])), true, "#12");
137
138                         // Tests for vectors<->one dimensional arrays */
139                         Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
140                         Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
141
142                         Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr1.GetType ()), true, "#13");
143                         Assert.AreEqual (typeof (int[]).IsAssignableFrom (arr2.GetType ()), false, "#14");
144
145                         // Test that arrays of enums can be cast to their base types
146                         Assert.AreEqual (typeof (int[]).IsAssignableFrom (typeof (TypeCode[])), true, "#15");
147
148                         // Test that arrays of valuetypes can't be cast to arrays of
149                         // references
150                         Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (TypeCode[])), false, "#16");
151                         Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (TypeCode[])), false, "#17");
152                         Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (TypeCode[])), false, "#18");
153
154                         // Test that arrays of enums can't be cast to arrays of references
155                         Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (TheEnum[])), false, "#19");
156                         Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (TheEnum[])), false, "#20");
157                         Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (TheEnum[])), false, "#21");
158
159                         // Check that ValueType and Enum are recognized as reference types
160                         Assert.AreEqual (typeof (object).IsAssignableFrom (typeof (ValueType)), true, "#22");
161                         Assert.AreEqual (typeof (object).IsAssignableFrom (typeof (Enum)), true, "#23");
162                         Assert.AreEqual (typeof (ValueType).IsAssignableFrom (typeof (Enum)), true, "#24");
163
164                         Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (ValueType[])), true, "#25");
165                         Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (ValueType[])), true, "#26");
166                         Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (ValueType[])), false, "#27");
167
168                         Assert.AreEqual (typeof (object[]).IsAssignableFrom (typeof (Enum[])), true, "#28");
169                         Assert.AreEqual (typeof (ValueType[]).IsAssignableFrom (typeof (Enum[])), true, "#29");
170                         Assert.AreEqual (typeof (Enum[]).IsAssignableFrom (typeof (Enum[])), true, "#30");
171
172                         // Tests for byref types
173                         MethodInfo mi = typeof (TypeTest).GetMethod ("ByrefMethod", BindingFlags.Instance|BindingFlags.NonPublic);
174                         Assert.IsTrue (mi.GetParameters ()[2].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
175                         Assert.IsTrue (mi.GetParameters ()[1].ParameterType.IsAssignableFrom (mi.GetParameters ()[1].ParameterType));
176                 }
177
178                 [Test]
179                 public void TestIsSubclassOf () {
180                         Assert.IsTrue (typeof (ICloneable).IsSubclassOf (typeof (object)), "#01");
181
182                         // Tests for byref types
183                         Type paramType = typeof (TypeTest).GetMethod ("ByrefMethod", BindingFlags.Instance|BindingFlags.NonPublic).GetParameters () [0].ParameterType;
184                         Assert.IsTrue (!paramType.IsSubclassOf (typeof (ValueType)), "#02");
185                         //Assert.IsTrue (paramType.IsSubclassOf (typeof (Object)), "#03");
186                         Assert.IsTrue (!paramType.IsSubclassOf (paramType), "#04");
187                 }
188
189                 [Test]
190                 public void TestGetMethodImpl() {
191                         // Test binding of new slot methods (using no types)
192                         Assert.AreEqual (typeof (Base), typeof (Base).GetMethod("TestVoid").DeclaringType, "#01");
193                         Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetMethod ("TestVoid").DeclaringType, "#02");
194
195                         // Test binding of new slot methods (using types)
196                         Assert.AreEqual (typeof (Base), typeof (Base).GetMethod ("TestInt", new Type[] { typeof (int) }).DeclaringType, "#03");
197                         Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetMethod ("TestInt", new Type[] { typeof (int) }).DeclaringType, "#04");
198
199                         // Test overload resolution
200                         Assert.AreEqual (0, typeof (NewVTable).GetMethod ("Overload", new Type[0]).GetParameters ().Length, "#05");
201
202                         // Test byref parameters
203                         Assert.AreEqual (null, typeof (NewVTable).GetMethod ("byref_method", new Type[] { typeof (int) }), "#06");
204                         Type byrefInt = typeof (NewVTable).GetMethod ("byref_method").GetParameters ()[0].ParameterType;
205                         Assert.IsNotNull (typeof (NewVTable).GetMethod ("byref_method", new Type[] { byrefInt }), "#07");
206                 }
207
208                 [Test]
209                 public void TestGetPropertyImpl() {
210                         // Test getting property that is exact
211                         Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetProperty ("Item", new Type[1] { typeof (Int32) }).DeclaringType, "#01");
212
213                         // Test getting property that is not exact
214                         Assert.AreEqual (typeof (NewVTable), typeof (NewVTable).GetProperty ("Item", new Type[1] { typeof (Int16) }).DeclaringType, "#02");
215
216                         // Test overriding of properties when only the set accessor is overriden
217                         Assert.AreEqual (1, typeof (Derived1).GetProperties ().Length, "#03");
218                 }
219
220                 [StructLayout(LayoutKind.Explicit, Pack = 4, Size = 64)]
221                 public class Class1 {
222                 }
223
224                 [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
225                 public class Class2 {
226                 }
227
228 #if NET_2_0
229                 [Test]
230                 public void StructLayoutAttribute () {
231                         StructLayoutAttribute attr1 = typeof (TypeTest).StructLayoutAttribute;
232                         Assert.AreEqual (LayoutKind.Auto, attr1.Value);
233
234                         StructLayoutAttribute attr2 = typeof (Class1).StructLayoutAttribute;
235                         Assert.AreEqual (LayoutKind.Explicit, attr2.Value);
236                         Assert.AreEqual (4, attr2.Pack);
237                         Assert.AreEqual (64, attr2.Size);
238
239                         StructLayoutAttribute attr3 = typeof (Class2).StructLayoutAttribute;
240                         Assert.AreEqual (LayoutKind.Explicit, attr3.Value);
241                         Assert.AreEqual (CharSet.Unicode, attr3.CharSet);
242                 }
243 #endif
244
245                 [Test]
246                 public void Namespace () {
247                         Assert.AreEqual (null, typeof (NoNamespaceClass).Namespace);
248                 }
249
250                 public static void Reflected (ref int a) {
251                 }
252
253                 [Test]
254                 public void Name ()
255                 {
256                         Assert.AreEqual ("Int32&", typeof (TypeTest).GetMethod ("Reflected").GetParameters () [0].ParameterType.Name);
257                 }
258
259                 [Test]
260                 public void GetInterfaces () {
261                         Type[] t = typeof (Duper).GetInterfaces ();
262                         Assert.AreEqual (1, t.Length);
263                         Assert.AreEqual (typeof (ICloneable), t[0]);
264
265                         Type[] t2 = typeof (IFace3).GetInterfaces ();
266                         Assert.AreEqual (2, t2.Length);
267                 }
268
269                 public int AField;
270
271                 [Test]
272                 public void GetFieldIgnoreCase () {
273                         Assert.IsNotNull (typeof (TypeTest).GetField ("afield", BindingFlags.Instance|BindingFlags.Public|BindingFlags.IgnoreCase));
274                 }
275
276 #if NET_2_0
277                 public int Count {
278                         internal get {
279                                 return 0;
280                         }
281
282                         set {
283                         }
284                 }
285
286                 [Test]
287                 public void GetPropertyAccessorModifiers () {
288                         Assert.IsNotNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.Public));
289                         Assert.IsNull (typeof (TypeTest).GetProperty ("Count", BindingFlags.Instance | BindingFlags.NonPublic));
290                 }
291 #endif
292
293                 [Test]
294                 public void IsPrimitive () {
295                         Assert.IsTrue (typeof (IntPtr).IsPrimitive);
296                 }
297
298                 [Test]
299                 [Category("NotDotNet")]
300                 // Depends on the GAC working, which it doesn't durring make distcheck.
301                 [Category ("NotWorking")]
302                 public void GetTypeWithWhitespace () {
303                         Assert.IsNotNull (Type.GetType
304                                                    (@"System.Configuration.NameValueSectionHandler,
305                         System,
306 Version=1.0.5000.0,
307 Culture=neutral
308 ,
309 PublicKeyToken=b77a5c561934e089"));
310                 }
311                 
312                 [Test]
313                 public void ExerciseFilterName() {
314                         MemberInfo[] mi = typeof(Base).FindMembers(
315                                 MemberTypes.Method, 
316                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
317                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
318                             Type.FilterName, "*");
319                         Assert.AreEqual (4, mi.Length);
320                         mi = typeof(Base).FindMembers(
321                                 MemberTypes.Method, 
322                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
323                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
324                             Type.FilterName, "Test*");
325                         Assert.AreEqual (2, mi.Length);
326                         mi = typeof(Base).FindMembers(
327                                 MemberTypes.Method, 
328                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
329                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
330                             Type.FilterName, "TestVoid");
331                         Assert.AreEqual (1, mi.Length);
332                         mi = typeof(Base).FindMembers(
333                                 MemberTypes.Method, 
334                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
335                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
336                             Type.FilterName, "NonExistingMethod");
337                         Assert.AreEqual (0, mi.Length);
338                 }
339                 
340                 [Test]
341                 public void ExerciseFilterNameIgnoreCase() {
342                         MemberInfo[] mi = typeof(Base).FindMembers(
343                                 MemberTypes.Method, 
344                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
345                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
346                             Type.FilterNameIgnoreCase, "*");
347                         Assert.AreEqual (4, mi.Length);
348                         mi = typeof(Base).FindMembers(
349                                 MemberTypes.Method, 
350                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
351                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
352                             Type.FilterNameIgnoreCase, "test*");
353                         Assert.AreEqual (2, mi.Length);
354                         mi = typeof(Base).FindMembers(
355                                 MemberTypes.Method, 
356                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
357                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
358                             Type.FilterNameIgnoreCase, "TESTVOID");
359                         Assert.AreEqual (1, mi.Length);
360                         mi = typeof(Base).FindMembers(
361                                 MemberTypes.Method, 
362                                 BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic |
363                             BindingFlags.Instance | BindingFlags.DeclaredOnly,
364                             Type.FilterNameIgnoreCase, "NonExistingMethod");
365                         Assert.AreEqual (0, mi.Length);
366                 }
367
368                 public class ByRef0 {
369                         public int field;
370                         public int property {
371                                 get { return 0; }
372                         }
373                         public ByRef0 (int i) {}
374                         public void f (int i) {}
375                 }
376
377                 [Test]
378                 public void ByrefTypes ()
379                 {
380                         Type t = Type.GetType ("MonoTests.System.TypeTest+ByRef0&");
381                         Assert.IsNotNull (t);
382                         Assert.IsTrue (t.IsByRef);
383                         Assert.AreEqual (0, t.GetMethods (BindingFlags.Public | BindingFlags.Instance).Length);
384                         Assert.AreEqual (0, t.GetConstructors (BindingFlags.Public | BindingFlags.Instance).Length);
385                         Assert.AreEqual (0, t.GetEvents (BindingFlags.Public | BindingFlags.Instance).Length);
386                         Assert.AreEqual (0, t.GetProperties (BindingFlags.Public | BindingFlags.Instance).Length);
387
388                         Assert.IsNull (t.GetMethod ("f"));
389                         Assert.IsNull (t.GetField ("field"));
390                         Assert.IsNull (t.GetProperty ("property"));
391                 }
392
393                 struct B
394                 {
395                         int value;
396                 }
397
398                 [Test]
399                 public void CreateValueTypeNoCtor () {
400                         typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, null);
401                 }
402
403                 [Test]
404                 [ExpectedException (typeof (MissingMethodException))]
405                 public void CreateValueTypeNoCtorArgs () {
406                         typeof(B).InvokeMember ("", BindingFlags.CreateInstance, null, null, new object [] { 1 });
407                 }
408
409                 class X
410                 {
411                         public static int Value;
412                 }
413
414                 class Y  : X
415                 {
416                 }
417
418                 [Test]
419                 public void InvokeMemberGetSetField () {
420                         typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.SetField, null, null, new object [] { 5 });
421
422                         Assert.AreEqual (5, X.Value);
423                         Assert.AreEqual (5, typeof (X).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
424                         Assert.AreEqual (5, Y.Value);
425                         Assert.AreEqual (5, typeof (Y).InvokeMember ("Value", BindingFlags.Public|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.GetField, null, null, new object [0]));
426                 }                       
427
428                 class Z {
429                         public Z (IComparable value) {}
430                 }
431         
432                 [Test]
433                 public void InvokeMemberMatchPrimitiveTypeWithInterface () {
434                         object[] invokeargs = {1};
435                         typeof (Z).InvokeMember( "", 
436                                                                                         BindingFlags.DeclaredOnly |
437                                                                                         BindingFlags.Public |
438                                                                                         BindingFlags.NonPublic |
439                                                                                         BindingFlags.Instance |
440                                                                                         BindingFlags.CreateInstance,
441                                                                                         null, null, invokeargs 
442                                                                                         );
443                 }
444
445                 class TakesInt {
446                         private int i;
447
448                         public TakesInt (int x)
449                         {
450                                 i = x;
451                         }
452
453                         public int Integer {
454                                 get { return i; }
455                         }
456                 }
457
458                 class TakesObject {
459                         public TakesObject (object x) {}
460                 }
461
462                 // Filed as bug #75241
463                 [Test]
464                 public void GetConstructorNullInTypes ()
465                 {
466                         // This ends up calling type.GetConstructor ()
467                         Activator.CreateInstance (typeof (TakesInt), new object [] { null });
468                         Activator.CreateInstance (typeof (TakesObject), new object [] { null });
469                 }
470
471                 [Test]
472                 [ExpectedException (typeof (ArgumentNullException))]
473                 public void GetConstructorNullInTypes_Bug71300 ()
474                 {
475                         typeof (TakesInt).GetConstructor (new Type[1] { null });
476                         // so null in types isn't valid for GetConstructor!
477                 }
478
479                 [Test]
480                 public void GetConstructor_TakeInt_Object ()
481                 {
482                         Assert.IsNull (typeof (TakesInt).GetConstructor (new Type[1] { typeof (object) }));
483                 }
484
485                 // bug #76150
486                 [Test]
487                 public void IsDefined ()
488                 {
489                         Assert.IsTrue (typeof (A).IsDefined (typeof (NemerleAttribute), false), "#1");
490                         Assert.IsTrue (typeof (A).IsDefined (typeof (VolatileModifier), false), "#2");
491                 }
492
493                 [Test]
494                 public void GetTypeCode ()
495                 {
496                         Assert.AreEqual (TypeCode.Boolean, Type.GetTypeCode (typeof (bool)), "#1");
497                         Assert.AreEqual (TypeCode.Byte, Type.GetTypeCode (typeof (byte)), "#2");
498                         Assert.AreEqual (TypeCode.Char, Type.GetTypeCode (typeof (char)), "#3");
499                         Assert.AreEqual (TypeCode.DateTime, Type.GetTypeCode (typeof (DateTime)), "#4");
500                         Assert.AreEqual (TypeCode.DBNull, Type.GetTypeCode (typeof (DBNull)), "#5");
501                         Assert.AreEqual (TypeCode.Decimal, Type.GetTypeCode (typeof (decimal)), "#6");
502                         Assert.AreEqual (TypeCode.Double, Type.GetTypeCode (typeof (double)), "#7");
503                         Assert.AreEqual (TypeCode.Empty, Type.GetTypeCode (null), "#8");
504                         Assert.AreEqual (TypeCode.Int16, Type.GetTypeCode (typeof (short)), "#9");
505                         Assert.AreEqual (TypeCode.Int32, Type.GetTypeCode (typeof (int)), "#10");
506                         Assert.AreEqual (TypeCode.Int64, Type.GetTypeCode (typeof (long)), "#11");
507                         Assert.AreEqual (TypeCode.Object, Type.GetTypeCode (typeof (TakesInt)), "#12");
508                         Assert.AreEqual (TypeCode.SByte, Type.GetTypeCode (typeof (sbyte)), "#13");
509                         Assert.AreEqual (TypeCode.Single, Type.GetTypeCode (typeof (float)), "#14");
510                         Assert.AreEqual (TypeCode.String, Type.GetTypeCode (typeof (string)), "#15");
511                         Assert.AreEqual (TypeCode.UInt16, Type.GetTypeCode (typeof (ushort)), "#16");
512                         Assert.AreEqual (TypeCode.UInt32, Type.GetTypeCode (typeof (uint)), "#17");
513                         Assert.AreEqual (TypeCode.UInt64, Type.GetTypeCode (typeof (ulong)), "#18");
514                 }
515
516                 [Test]
517                 [ExpectedException (typeof (ArgumentNullException))]
518                 public void GetConstructor1a_Bug71300 ()
519                 {
520                         typeof (BindingFlags).GetConstructor (null);
521                 }
522
523                 [Test]
524                 [ExpectedException (typeof (ArgumentNullException))]
525                 public void GetConstructor1b_Bug71300 ()
526                 {
527                         typeof (BindingFlags).GetConstructor (new Type[1] { null });
528                 }
529
530                 [Test]
531                 [ExpectedException (typeof (ArgumentNullException))]
532                 public void GetConstructor4_Bug71300 ()
533                 {
534                         typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, new Type[1] { null }, null);
535                 }
536
537                 [Test]
538                 [ExpectedException (typeof (ArgumentNullException))]
539                 public void GetConstructor5_Bug71300 ()
540                 {
541                         typeof (BindingFlags).GetConstructor (BindingFlags.Default, null, CallingConventions.Any, new Type[1] { null }, null);
542                 }
543
544                 [Test]
545                 public void GetMethod_Bug77367 ()
546                 {
547                         MethodInfo i = typeof (Bug77367).GetMethod ("Run", Type.EmptyTypes);
548                         Assert.IsNull (i);
549                 }
550
551 #if NET_2_0
552                 [Test]
553                 public void FullNameGenerics ()
554                 {
555                         Type fooType = typeof (Foo<>);
556                         FieldInfo [] fields = fooType.GetFields ();
557
558                         Assert.AreEqual (1, fields.Length, "#0");
559
560                         Assert.IsNotNull (fooType.FullName, "#1");
561                         Assert.IsNotNull (fooType.AssemblyQualifiedName, "#1a");
562
563                         FieldInfo field = fooType.GetField ("Whatever");
564                         Assert.IsNotNull (field, "#2");
565                         Assert.AreEqual (field, fields [0], "#2a");
566                         Assert.IsNull (field.FieldType.FullName, "#3");
567                         Assert.IsNull (field.FieldType.AssemblyQualifiedName, "#3a");
568                         Assert.IsNotNull (field.FieldType.ToString (), "#4");
569
570                         PropertyInfo prop = fooType.GetProperty ("Test");
571                         Assert.IsNotNull (prop, "#5");
572                         Assert.IsNull (prop.PropertyType.FullName, "#6");
573                         Assert.IsNull (prop.PropertyType.AssemblyQualifiedName, "#6a");
574                         Assert.IsNotNull (prop.PropertyType.ToString (), "#7");
575
576                         MethodInfo method = fooType.GetMethod("Execute");
577                         Assert.IsNotNull (method, "#8");
578                         Assert.IsNull (method.ReturnType.FullName, "#9");
579                         Assert.IsNull (method.ReturnType.AssemblyQualifiedName, "#9a");
580                         Assert.IsNotNull (method.ReturnType.ToString (), "#10");
581
582                         ParameterInfo[] parameters = method.GetParameters();
583                         Assert.AreEqual (1, parameters.Length, "#11");
584                         Assert.IsNull (parameters[0].ParameterType.FullName, "#12");
585                         Assert.IsNull (parameters[0].ParameterType.AssemblyQualifiedName, "#12a");
586                         Assert.IsNotNull (parameters[0].ParameterType.ToString (), "#13");
587                 }
588
589                 [Test]
590                 public void TypeParameterIsNotGeneric ()
591                 {
592                         Type fooType = typeof (Foo<>);
593                         Type type_param = fooType.GetGenericArguments () [0];
594                         Assert.IsTrue (type_param.IsGenericParameter);
595                         Assert.IsFalse (type_param.IsGenericType);
596                         Assert.IsFalse (type_param.IsGenericTypeDefinition);
597
598                         // LAMESPEC: MSDN claims that this should be false, but .NET v2.0.50727 says it's true
599                         // http://msdn2.microsoft.com/en-us/library/system.type.isgenerictype.aspx
600                         Assert.IsTrue (type_param.ContainsGenericParameters);
601                 }
602
603                 [Test]
604                 public void IsAssignable ()
605                 {
606                         Type foo_type = typeof (Foo<>);
607                         Type foo_int_type = typeof (Foo<int>);
608                         Assert.IsFalse (foo_type.IsAssignableFrom (foo_int_type), "Foo<int> -!-> Foo<>");
609                         Assert.IsFalse (foo_int_type.IsAssignableFrom (foo_type), "Foo<> -!-> Foo<int>");
610
611                         Type ibar_short_type = typeof (IBar<short>);
612                         Type ibar_int_type = typeof (IBar<int>);
613                         Type baz_short_type = typeof (Baz<short>);
614                         Type baz_int_type = typeof (Baz<int>);
615
616                         Assert.IsTrue (ibar_int_type.IsAssignableFrom (baz_int_type), "Baz<int> -> IBar<int>");
617                         Assert.IsTrue (ibar_short_type.IsAssignableFrom (baz_short_type), "Baz<short> -> IBar<short>");
618
619                         Assert.IsFalse (ibar_int_type.IsAssignableFrom (baz_short_type), "Baz<short> -!-> IBar<int>");
620                         Assert.IsFalse (ibar_short_type.IsAssignableFrom (baz_int_type), "Baz<int> -!-> IBar<short>");
621
622                         // Nullable tests
623                         Assert.IsTrue (typeof (Nullable<int>).IsAssignableFrom (typeof (int)));
624                         Assert.IsFalse (typeof (int).IsAssignableFrom (typeof (Nullable<int>)));
625                         Assert.IsTrue (typeof (Nullable<FooStruct>).IsAssignableFrom (typeof (FooStruct)));
626                 }
627
628                 [Test]
629                 public void IsInstanceOf ()
630                 {
631                         Assert.IsTrue (typeof (Nullable<int>).IsInstanceOfType (5));
632                 }
633
634                 [Test]
635                 public void ByrefType ()
636                 {
637                         Type foo_type = typeof (Foo<>);
638                         Type type_param = foo_type.GetGenericArguments () [0];
639                         Type byref_type_param = type_param.MakeByRefType ();
640                         Assert.IsFalse (byref_type_param.IsGenericParameter);
641                         Assert.IsNull (byref_type_param.DeclaringType);
642                 }
643
644                 [Test]
645                 [Category ("NotWorking")] // BindingFlags.SetField throws since args.Length != 1, even though we have SetProperty
646                 public void Bug79023 ()
647                 {
648                         ArrayList list = new ArrayList();
649                         list.Add("foo");
650
651                         // The next line used to throw because we had SetProperty
652                         list.GetType().InvokeMember("Item",
653                                                     BindingFlags.SetField|BindingFlags.SetProperty|
654                                                     BindingFlags.Instance|BindingFlags.Public,
655                                                     null, list, new object[] { 0, "bar" });
656                         Assert.AreEqual ("bar", list[0]);
657                 }
658                 
659                 [ComVisible (true)]
660                 public class ComFoo<T> {
661                 }
662
663                 [Test]
664                 public void GetCustomAttributesGenericInstance ()
665                 {
666                         Assert.AreEqual (1, typeof (ComFoo<int>).GetCustomAttributes (typeof (ComVisibleAttribute), true).Length);
667                 }
668
669                 interface ByRef1<T> { void f (ref T t); }
670                 interface ByRef2 { void f<T> (ref T t); }
671
672                 interface ByRef3<T> where T:struct { void f (ref T? t); }
673                 interface ByRef4 { void f<T> (ref T? t) where T:struct; }
674
675                 void CheckGenericByRef (Type t)
676                 {
677                         string name = t.Name;
678                         t = t.GetMethod ("f").GetParameters () [0].ParameterType;
679
680                         Assert.IsFalse (t.IsGenericType, name);
681                         Assert.IsFalse (t.IsGenericTypeDefinition, name);
682                         Assert.IsFalse (t.IsGenericParameter, name);
683                 }
684
685                 [Test]
686                 public void GenericByRef ()
687                 {
688                         CheckGenericByRef (typeof (ByRef1<>));
689                         CheckGenericByRef (typeof (ByRef2));
690                         CheckGenericByRef (typeof (ByRef3<>));
691                         CheckGenericByRef (typeof (ByRef4));
692                 }
693 #endif
694
695                 public class NemerleAttribute : Attribute
696                 { }
697
698                 public class VolatileModifier : NemerleAttribute
699                 { }
700
701                 [VolatileModifier]
702                 class A { }
703
704                 struct FooStruct {
705                 }
706
707                 public class Bug77367
708                 {
709                         public void Run (bool b)
710                         {
711                         }
712                 }
713
714         }
715 }