2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / System / Type.cs
1 //
2 // System.Type.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) Ximian, Inc.  http://www.ximian.com
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Diagnostics;
34 using System.Reflection;
35 using System.Reflection.Emit;
36 using System.Collections;
37 using System.Runtime.InteropServices;
38 using System.Runtime.CompilerServices;
39 using System.Globalization;
40
41 namespace System {
42
43         [Serializable]
44         [ClassInterface (ClassInterfaceType.None)]
45         [ComVisible (true)]
46         [ComDefaultInterface (typeof (_Type))]
47         public abstract class Type : MemberInfo, IReflect, _Type {
48                 
49                 internal RuntimeTypeHandle _impl;
50
51                 public static readonly char Delimiter = '.';
52                 public static readonly Type[] EmptyTypes = {};
53                 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
54                 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
55                 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
56                 public static readonly object Missing = System.Reflection.Missing.Value;
57
58                 internal const BindingFlags DefaultBindingFlags =
59                 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
60
61                 /* implementation of the delegates for MemberFilter */
62                 static bool FilterName_impl (MemberInfo m, object filterCriteria)
63                 {
64                         string name = (string) filterCriteria;
65                         if (name == null || name.Length == 0 )
66                                 return false; // because m.Name cannot be null or empty
67                                 
68                         if (name [name.Length-1] == '*')
69                                 return string.CompareOrdinal (name, 0, m.Name, 0, name.Length-1) == 0;
70
71                 return name.Equals (m.Name);                    
72                 }
73
74                 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
75                 {
76                         string name = (string) filterCriteria;
77                         if (name == null || name.Length == 0 )
78                                 return false; // because m.Name cannot be null or empty
79                                 
80                         if (name [name.Length-1] == '*')
81                                 return string.Compare (name, 0, m.Name, 0, name.Length-1, StringComparison.OrdinalIgnoreCase) == 0;
82
83                         return string.Equals (name, m.Name, StringComparison.OrdinalIgnoreCase);
84                 }
85
86                 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
87                 {
88                         int flags = ((IConvertible)filterCriteria).ToInt32 (null);
89                         if (m is MethodInfo)
90                                 return ((int)((MethodInfo)m).Attributes & flags) != 0;
91                         if (m is FieldInfo)
92                                 return ((int)((FieldInfo)m).Attributes & flags) != 0;
93                         if (m is PropertyInfo)
94                                 return ((int)((PropertyInfo)m).Attributes & flags) != 0;
95                         if (m is EventInfo)
96                                 return ((int)((EventInfo)m).Attributes & flags) != 0;
97                         return false;
98                 }
99
100                 protected Type ()
101                 {
102                 }
103
104                 /// <summary>
105                 ///   The assembly where the type is defined.
106                 /// </summary>
107                 public abstract Assembly Assembly {
108                         get;
109                 }
110
111                 /// <summary>
112                 ///   Gets the fully qualified name for the type including the
113                 ///   assembly name where the type is defined.
114                 /// </summary>
115                 public abstract string AssemblyQualifiedName {
116                         get;
117                 }
118
119                 /// <summary>
120                 ///   Returns the Attributes associated with the type.
121                 /// </summary>
122                 public TypeAttributes Attributes {
123                         get {
124                                 return GetAttributeFlagsImpl ();
125                         }
126                 }
127
128                 /// <summary>
129                 ///   Returns the basetype for this type
130                 /// </summary>
131                 public abstract Type BaseType {
132                         get;
133                 }
134
135                 /// <summary>
136                 ///   Returns the class that declares the member.
137                 /// </summary>
138                 public override Type DeclaringType {
139                         get {
140                                 return null;
141                         }
142                 }
143
144                 /// <summary>
145                 ///
146                 /// </summary>
147                 public static Binder DefaultBinder {
148                         get {
149                                 return Binder.DefaultBinder;
150                         }
151                 }
152
153                 /// <summary>
154                 ///    The full name of the type including its namespace
155                 /// </summary>
156                 public abstract string FullName {
157                         get;
158                 }
159
160                 public abstract Guid GUID {
161                         get;
162                 }
163
164                 public bool HasElementType {
165                         get {
166                                 return HasElementTypeImpl ();
167                         }
168                 }
169
170                 public bool IsAbstract {
171                         get {
172                                 return (Attributes & TypeAttributes.Abstract) != 0;
173                         }
174                 }
175
176                 public bool IsAnsiClass {
177                         get {
178                                 return (Attributes & TypeAttributes.StringFormatMask)
179                                 == TypeAttributes.AnsiClass;
180                         }
181                 }
182
183                 public bool IsArray {
184                         get {
185                                 return IsArrayImpl ();
186                         }
187                 }
188
189                 public bool IsAutoClass {
190                         get {
191                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
192                         }
193                 }
194
195                 public bool IsAutoLayout {
196                         get {
197                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
198                         }
199                 }
200
201                 public bool IsByRef {
202                         get {
203                                 return IsByRefImpl ();
204                         }
205                 }
206
207                 public bool IsClass {
208                         get {
209                                 if (IsInterface)
210                                         return false;
211
212                                 return !IsValueType;
213                         }
214                 }
215
216                 public bool IsCOMObject {
217                         get {
218                                 return IsCOMObjectImpl ();
219                         }
220                 }
221
222                 public bool IsContextful {
223                         get {
224                                 return IsContextfulImpl ();
225                         }
226                 }
227
228                 public
229 #if NET_4_0
230                 virtual
231 #endif
232                 bool IsEnum {
233                         get {
234                                 return IsSubclassOf (typeof (Enum));
235                         }
236                 }
237
238                 public bool IsExplicitLayout {
239                         get {
240                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
241                         }
242                 }
243
244                 public bool IsImport {
245                         get {
246                                 return (Attributes & TypeAttributes.Import) != 0;
247                         }
248                 }
249
250                 public bool IsInterface {
251                         get {
252                                 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
253                         }
254                 }
255
256                 public bool IsLayoutSequential {
257                         get {
258                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
259                         }
260                 }
261
262                 public bool IsMarshalByRef {
263                         get {
264                                 return IsMarshalByRefImpl ();
265                         }
266                 }
267
268                 public bool IsNestedAssembly {
269                         get {
270                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
271                         }
272                 }
273
274                 public bool IsNestedFamANDAssem {
275                         get {
276                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
277                         }
278                 }
279
280                 public bool IsNestedFamily {
281                         get {
282                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
283                         }
284                 }
285
286                 public bool IsNestedFamORAssem {
287                         get {
288                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
289                         }
290                 }
291
292                 public bool IsNestedPrivate {
293                         get {
294                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
295                         }
296                 }
297
298                 public bool IsNestedPublic {
299                         get {
300                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
301                         }
302                 }
303
304                 public bool IsNotPublic {
305                         get {
306                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
307                         }
308                 }
309
310                 public bool IsPointer {
311                         get {
312                                 return IsPointerImpl ();
313                         }
314                 }
315
316                 public bool IsPrimitive {
317                         get {
318                                 return IsPrimitiveImpl ();
319                         }
320                 }
321
322                 public bool IsPublic {
323                         get {
324                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
325                         }
326                 }
327
328                 public bool IsSealed {
329                         get {
330                                 return (Attributes & TypeAttributes.Sealed) != 0;
331                         }
332                 }
333
334                 public
335 #if NET_4_0
336                 virtual
337 #endif
338                 bool IsSerializable {
339                         get {
340                                 if ((Attributes & TypeAttributes.Serializable) != 0)
341                                         return true;
342
343                                 // Enums and delegates are always serializable
344
345                                 Type type = UnderlyingSystemType;
346                                 if (type == null)
347                                         return false;
348
349                                 // Fast check for system types
350                                 if (type.IsSystemType)
351                                         return type_is_subtype_of (type, typeof (Enum), false) || type_is_subtype_of (type, typeof (Delegate), false);
352
353                                 // User defined types depend on this behavior
354                                 do {
355                                         if ((type == typeof (Enum)) || (type == typeof (Delegate)))
356                                                 return true;
357
358                                         type = type.BaseType;
359                                 } while (type != null);
360
361                                 return false;
362                         }
363                 }
364
365                 public bool IsSpecialName {
366                         get {
367                                 return (Attributes & TypeAttributes.SpecialName) != 0;
368                         }
369                 }
370
371                 public bool IsUnicodeClass {
372                         get {
373                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
374                         }
375                 }
376
377                 public bool IsValueType {
378                         get {
379                                 return IsValueTypeImpl ();
380                         }
381                 }
382
383                 public override MemberTypes MemberType {
384                         get {return MemberTypes.TypeInfo;}
385                 }
386
387                 override
388                 public abstract Module Module {get;}
389         
390                 public abstract string Namespace {get;}
391
392                 public override Type ReflectedType {
393                         get {
394                                 return null;
395                         }
396                 }
397
398                 public virtual RuntimeTypeHandle TypeHandle {
399                         get { throw new ArgumentException ("Derived class must provide implementation."); }
400                 }
401
402                 [ComVisible (true)]
403                 public ConstructorInfo TypeInitializer {
404                         get {
405                                 return GetConstructorImpl (
406                                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
407                                         null,
408                                         CallingConventions.Any,
409                                         EmptyTypes,
410                                         null);
411                         }
412                 }
413
414                 /*
415                  * This has NOTHING to do with getting the base type of an enum. Use
416                  * Enum.GetUnderlyingType () for that.
417                  */
418                 public abstract Type UnderlyingSystemType {get;}
419
420                 public override bool Equals (object o)
421                 {
422 #if NET_4_0
423                         return Equals (o as Type);
424 #else
425                         if (o == this)
426                                 return true;
427
428                         Type me = UnderlyingSystemType;
429                         if (me == null)
430                                 return false;
431                         return me.EqualsInternal (o as Type);
432 #endif
433                 }
434
435 #if NET_4_0
436                 public virtual bool Equals (Type o)
437                 {
438                         if ((object)o == this)
439                                 return true;
440                         if ((object)o == null)
441                                 return false;
442                         Type me = UnderlyingSystemType;
443                         if ((object)me == null)
444                                 return false;
445
446                         o = o.UnderlyingSystemType;
447                         if ((object)o == null)
448                                 return false;
449                         if ((object)o == this)
450                                 return true;
451                         return me.EqualsInternal (o);
452                 }               
453 #else
454                 public bool Equals (Type o)
455                 {
456
457                         if (o == this)
458                                 return true;
459                         if (o == null)
460                                 return false;
461                         Type me = UnderlyingSystemType;
462                         if (me == null)
463                                 return false;
464                         return me.EqualsInternal (o.UnderlyingSystemType);
465                 }
466 #endif
467 #if NET_4_0
468                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
469                 public static bool operator == (Type left, Type right)
470                 {
471                         return Object.ReferenceEquals (left, right);
472                 }
473
474                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
475                 public static bool operator != (Type left, Type right)
476                 {
477                         return !Object.ReferenceEquals (left, right);
478                 }
479
480                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
481                 public virtual Type GetEnumUnderlyingType () {
482                         if (!IsEnum)
483                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
484
485                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
486
487                         if (fields == null || fields.Length != 1)
488                                 throw new ArgumentException ("An enum must have exactly one instance field", "enumType");
489
490                         return fields [0].FieldType;
491                 }
492
493                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
494                 public virtual string[] GetEnumNames () {
495                         if (!IsEnum)
496                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
497
498                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
499
500                         string [] result = new string [fields.Length];
501                         for (int i = 0; i < fields.Length; ++i)
502                                 result [i] = fields [i].Name;
503
504                         return result;
505                 }
506
507                 NotImplementedException CreateNIE () {
508                         return new NotImplementedException ();
509                 }
510
511                 public virtual Array GetEnumValues () {
512                         if (!IsEnum)
513                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
514
515                         throw CreateNIE ();
516                 }
517
518                 bool IsValidEnumType (Type type) {
519                         return (type.IsPrimitive && type != typeof (bool) && type != typeof (double) && type != typeof (float)) || type.IsEnum;
520                 }
521
522                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
523                 public virtual string GetEnumName (object value) {
524                         if (value == null)
525                                 throw new ArgumentException ("Value is null", "value");
526                         if (!IsValidEnumType (value.GetType ()))
527                                 throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
528                         if (!IsEnum)
529                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
530
531                         object obj = null;
532                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
533                         
534                         for (int i = 0; i < fields.Length; ++i) {
535                                 var fv = fields [i].GetValue (null);
536                                 if (obj == null) {
537                                         try {
538                                                 //XXX we can't use 'this' as argument as it might be an UserType
539                                                 obj = Enum.ToObject (fv.GetType (), value);
540                                         } catch (OverflowException) {
541                                                 return null;
542                                         } catch (InvalidCastException) {
543                                                 throw new ArgumentException ("Value is not valid", "value");
544                                         }
545                                 }
546                                 if (fv.Equals (obj))
547                                         return fields [i].Name;
548                         }
549
550                         return null;
551                 }
552
553                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
554                 public virtual bool IsEnumDefined (object value) {
555                         if (value == null)
556                                 throw new ArgumentException ("Value is null", "value");
557                         if (!IsEnum)
558                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
559
560                         Type vt = value.GetType ();
561                         if (!IsValidEnumType (vt) && vt != typeof (string))
562                                 throw new InvalidOperationException ("Value is not the enum or a valid enum underlying type");
563
564                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
565
566                         if (value is string) {
567                                 for (int i = 0; i < fields.Length; ++i) {
568                                         if (fields [i].Name.Equals (value))
569                                                 return true;
570                                 }
571                         } else {
572                                 if (vt != this && vt != GetEnumUnderlyingType ())
573                                         throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
574
575                                 object obj = null;
576                                 for (int i = 0; i < fields.Length; ++i) {
577                                         var fv = fields [i].GetValue (null);
578                                         if (obj == null) {
579                                                 try {
580                                                         //XXX we can't use 'this' as argument as it might be an UserType
581                                                         obj = Enum.ToObject (fv.GetType (), value);
582                                                 } catch (OverflowException) {
583                                                         return false;
584                                                 } catch (InvalidCastException) {
585                                                         throw new ArgumentException ("Value is not valid", "value");
586                                                 }
587                                         }
588                                         if (fv.Equals (obj))
589                                                 return true;
590                                 }
591                         }
592                         return false;
593                 }
594         
595                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver)
596                 {
597                         return GetType (typeName, assemblyResolver, typeResolver, false, false);
598                 }
599         
600                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError)
601                 {
602                         return GetType (typeName, assemblyResolver, typeResolver, throwOnError, false);
603                 }
604         
605                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError, bool ignoreCase)
606                 {
607                         TypeSpec spec = TypeSpec.Parse (typeName);
608                         return spec.Resolve (assemblyResolver, typeResolver, throwOnError, ignoreCase);
609                 }
610
611                 public virtual bool IsSecurityTransparent
612                 {
613                         get { throw CreateNIE (); }
614                 }
615
616                 public virtual bool IsSecurityCritical
617                 {
618                         get { throw CreateNIE (); }
619                 }
620
621                 public virtual bool IsSecuritySafeCritical
622                 {
623                         get { throw CreateNIE (); }
624                 }
625 #endif
626                 
627                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
628                 internal extern bool EqualsInternal (Type type);
629                 
630                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
631                 private static extern Type internal_from_handle (IntPtr handle);
632                 
633                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
634                 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
635
636                 public static Type GetType(string typeName)
637                 {
638                         if (typeName == null)
639                                 throw new ArgumentNullException ("TypeName");
640
641                         return internal_from_name (typeName, false, false);
642                 }
643
644                 public static Type GetType(string typeName, bool throwOnError)
645                 {
646                         if (typeName == null)
647                                 throw new ArgumentNullException ("TypeName");
648
649                         Type type = internal_from_name (typeName, throwOnError, false);
650                         if (throwOnError && type == null)
651                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
652
653                         return type;
654                 }
655
656                 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
657                 {
658                         if (typeName == null)
659                                 throw new ArgumentNullException ("TypeName");
660
661                         Type t = internal_from_name (typeName, throwOnError, ignoreCase);
662                         if (throwOnError && t == null)
663                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
664
665                         return t;
666                 }
667
668                 public static Type[] GetTypeArray (object[] args) {
669                         if (args == null)
670                                 throw new ArgumentNullException ("args");
671
672                         Type[] ret;
673                         ret = new Type [args.Length];
674                         for (int i = 0; i < args.Length; ++i)
675                                 ret [i] = args[i].GetType ();
676                         return ret;
677                 }
678
679                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
680                 internal extern static TypeCode GetTypeCodeInternal (Type type);
681
682 #if NET_4_0
683                 protected virtual
684 #endif
685                 TypeCode GetTypeCodeImpl () {
686                         Type type = this;
687                         if (type is MonoType)
688                                 return GetTypeCodeInternal (type);
689
690                         type = type.UnderlyingSystemType;
691
692                         if (!type.IsSystemType)
693                                 return TypeCode.Object;
694                         else
695                                 return GetTypeCodeInternal (type);
696                 }
697
698                 public static TypeCode GetTypeCode (Type type) {
699                         if (type == null)
700                                 /* MS.NET returns this */
701                                 return TypeCode.Empty;
702                         return type.GetTypeCodeImpl ();
703                 }
704
705                 [MonoTODO("This operation is currently not supported by Mono")]
706                 public static Type GetTypeFromCLSID (Guid clsid)
707                 {
708                         throw new NotImplementedException ();
709                 }
710
711                 [MonoTODO("This operation is currently not supported by Mono")]
712                 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
713                 {
714                         throw new NotImplementedException ();
715                 }
716
717                 [MonoTODO("This operation is currently not supported by Mono")]
718                 public static Type GetTypeFromCLSID (Guid clsid, string server)
719                 {
720                         throw new NotImplementedException ();
721                 }
722
723                 [MonoTODO("This operation is currently not supported by Mono")]
724                 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
725                 {
726                         throw new NotImplementedException ();
727                 }
728
729                 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
730                 {
731                         if (handle.Value == IntPtr.Zero)
732                                 // This is not consistent with the other GetXXXFromHandle methods, but
733                                 // MS.NET seems to do this
734                                 return null;
735
736                         return internal_from_handle (handle.Value);
737                 }
738
739                 [MonoTODO("Mono does not support COM")]
740                 public static Type GetTypeFromProgID (string progID)
741                 {
742                         throw new NotImplementedException ();
743                 }
744
745                 [MonoTODO("Mono does not support COM")]
746                 public static Type GetTypeFromProgID (string progID, bool throwOnError)
747                 {
748                         throw new NotImplementedException ();
749                 }
750
751                 [MonoTODO("Mono does not support COM")]
752                 public static Type GetTypeFromProgID (string progID, string server)
753                 {
754                         throw new NotImplementedException ();
755                 }
756
757                 [MonoTODO("Mono does not support COM")]
758                 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
759                 {
760                         throw new NotImplementedException ();
761                 }
762
763                 public static RuntimeTypeHandle GetTypeHandle (object o)
764                 {
765                         if (o == null)
766                                 throw new ArgumentNullException ();
767
768                         return o.GetType().TypeHandle;
769                 }
770
771                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
772                 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
773
774                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
775                 internal static extern bool type_is_assignable_from (Type a, Type b);
776
777                 public new Type GetType ()
778                 {
779                         return base.GetType ();
780                 }
781
782                 [ComVisible (true)]
783                 public virtual bool IsSubclassOf (Type c)
784                 {
785                         if (c == null || c == this)
786                                 return false;
787
788                         // Fast check for system types
789                         if (IsSystemType)
790                                 return c.IsSystemType && type_is_subtype_of (this, c, false);
791
792                         // User defined types depend on this behavior
793                         for (Type type = BaseType; type != null; type = type.BaseType)
794                                 if (type == c)
795                                         return true;
796
797                         return false;
798                 }
799
800                 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
801                 {
802                         if (filter == null)
803                                 throw new ArgumentNullException ("filter");
804
805                         ArrayList ifaces = new ArrayList ();
806                         foreach (Type iface in GetInterfaces ()) {
807                                 if (filter (iface, filterCriteria))
808                                         ifaces.Add (iface);
809                         }
810
811                         return (Type []) ifaces.ToArray (typeof (Type));
812                 }
813                 
814                 public Type GetInterface (string name) {
815                         return GetInterface (name, false);
816                 }
817
818                 public abstract Type GetInterface (string name, bool ignoreCase);
819
820                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
821                 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
822
823                 [ComVisible (true)]
824                 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
825                         if (!IsSystemType)
826                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
827                         if (!interfaceType.IsSystemType)
828                                 throw new ArgumentException ("interfaceType", "Type is an user type");
829                         InterfaceMapping res;
830                         if (interfaceType == null)
831                                 throw new ArgumentNullException ("interfaceType");
832                         if (!interfaceType.IsInterface)
833                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType");
834                         if (IsInterface)
835                                 throw new ArgumentException ("'this' type cannot be an interface itself");
836                         res.TargetType = this;
837                         res.InterfaceType = interfaceType;
838                         GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
839                         if (res.TargetMethods == null)
840                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType");
841
842                         return res;
843                 }
844
845                 public abstract Type[] GetInterfaces ();
846
847                 public virtual bool IsAssignableFrom (Type c)
848                 {
849                         if (c == null)
850                                 return false;
851
852                         if (Equals (c))
853                                 return true;
854
855                         if (c is TypeBuilder)
856                                 return ((TypeBuilder)c).IsAssignableTo (this);
857
858                         /* Handle user defined type classes */
859                         if (!IsSystemType) {
860                                 Type systemType = UnderlyingSystemType;
861                                 if (!systemType.IsSystemType)
862                                         return false;
863
864                                 Type other = c.UnderlyingSystemType;
865                                 if (!other.IsSystemType)
866                                         return false;
867
868                                 return systemType.IsAssignableFrom (other);
869                         }
870
871                         if (!c.IsSystemType) {
872                                 Type underlyingType = c.UnderlyingSystemType;
873                                 if (!underlyingType.IsSystemType)
874                                         return false;
875                                 return IsAssignableFrom (underlyingType);
876                         }
877
878                         return type_is_assignable_from (this, c);
879                 }
880
881                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
882                 extern static bool IsInstanceOfType (Type type, object o);
883
884                 public virtual bool IsInstanceOfType (object o)
885                 {
886                         Type type = UnderlyingSystemType;
887                         if (!type.IsSystemType)
888                                 return false;
889                         return IsInstanceOfType (type, o);
890                 }
891
892                 public virtual int GetArrayRank ()
893                 {
894                         throw new NotSupportedException ();     // according to MSDN
895                 }
896
897                 public abstract Type GetElementType ();
898
899                 public EventInfo GetEvent (string name)
900                 {
901                         return GetEvent (name, DefaultBindingFlags);
902                 }
903
904                 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
905
906                 public virtual EventInfo[] GetEvents ()
907                 {
908                         return GetEvents (DefaultBindingFlags);
909                 }
910
911                 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
912
913                 public FieldInfo GetField( string name)
914                 {
915                         return GetField (name, DefaultBindingFlags);
916                 }
917
918                 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
919
920                 public FieldInfo[] GetFields ()
921                 {
922                         return GetFields (DefaultBindingFlags);
923                 }
924
925                 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
926                 
927                 public override int GetHashCode()
928                 {
929                         Type t = UnderlyingSystemType;
930                         if (t != null && t != this)
931                                 return t.GetHashCode ();
932                         return (int)_impl.Value;
933                 }
934
935                 public MemberInfo[] GetMember (string name)
936                 {
937                         return GetMember (name, MemberTypes.All, DefaultBindingFlags);
938                 }
939                 
940                 public virtual MemberInfo[] GetMember (string name, BindingFlags bindingAttr)
941                 {
942                         return GetMember (name, MemberTypes.All, bindingAttr);
943                 }
944
945                 public virtual MemberInfo[] GetMember (string name, MemberTypes type, BindingFlags bindingAttr)
946                 {
947                         if (name == null)
948                                 throw new ArgumentNullException ("name");
949                         if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
950                                 return FindMembers (type, bindingAttr, FilterNameIgnoreCase, name);
951                         else
952                                 return FindMembers (type, bindingAttr, FilterName, name);
953                 }
954
955                 public MemberInfo[] GetMembers ()
956                 {
957                         return GetMembers (DefaultBindingFlags);
958                 }
959
960                 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
961
962                 public MethodInfo GetMethod (string name)
963                 {
964                         if (name == null)
965                                 throw new ArgumentNullException ("name");
966                         return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
967                 }
968
969                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
970                 {
971                         if (name == null)
972                                 throw new ArgumentNullException ("name");
973                         
974                         return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
975                 }
976                 
977                 public MethodInfo GetMethod (string name, Type[] types)
978                 {
979                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
980                 }
981
982                 public MethodInfo GetMethod (string name, Type[] types, ParameterModifier[] modifiers)
983                 {
984                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, modifiers);
985                 }
986
987                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
988                                              Type[] types, ParameterModifier[] modifiers)
989                 {
990                         return GetMethod (name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
991                 }
992
993                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
994                                              CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
995                 {
996                         if (name == null)
997                                 throw new ArgumentNullException ("name");
998                         if (types == null)
999                                 throw new ArgumentNullException ("types");
1000
1001                         for (int i = 0; i < types.Length; i++) 
1002                                 if (types[i] == null)
1003                                         throw new ArgumentNullException ("types");
1004
1005                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1006                 }
1007
1008                 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
1009                                                              CallingConventions callConvention, Type[] types,
1010                                                              ParameterModifier[] modifiers);
1011
1012                 internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1013                                                                                                                         CallingConventions callConvention, Type[] types,
1014                                                                                                                         ParameterModifier[] modifiers)
1015                 {
1016                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1017                 }
1018
1019                 internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated)
1020                 {
1021                         throw new System.InvalidOperationException ("can only be called in generic type");
1022                 }
1023
1024                 internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
1025                 {
1026                         throw new System.InvalidOperationException ("can only be called in generic type");
1027                 }
1028
1029                 internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated)
1030                 {
1031                         throw new System.InvalidOperationException ("can only be called in generic type");
1032                 }
1033
1034                 
1035                 public MethodInfo[] GetMethods ()
1036                 {
1037                         return GetMethods (DefaultBindingFlags);
1038                 }
1039
1040                 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
1041
1042                 public Type GetNestedType (string name)
1043                 {
1044                         return GetNestedType (name, DefaultBindingFlags);
1045                 }
1046
1047                 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
1048
1049                 public Type[] GetNestedTypes ()
1050                 {
1051                         return GetNestedTypes (DefaultBindingFlags);
1052                 }
1053
1054                 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
1055
1056
1057                 public PropertyInfo[] GetProperties ()
1058                 {
1059                         return GetProperties (DefaultBindingFlags);
1060                 }
1061
1062                 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
1063
1064
1065                 public PropertyInfo GetProperty (string name)
1066                 {
1067                         if (name == null)
1068                                 throw new ArgumentNullException ("name");
1069
1070                         return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null);
1071                 }
1072
1073                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
1074                 {
1075                         if (name == null)
1076                                 throw new ArgumentNullException ("name");
1077                         return GetPropertyImpl (name, bindingAttr, null, null, null, null);
1078                 }
1079
1080                 public PropertyInfo GetProperty (string name, Type returnType)
1081                 {
1082                         if (name == null)
1083                                 throw new ArgumentNullException ("name");
1084                         return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null);
1085                 }
1086
1087                 public PropertyInfo GetProperty (string name, Type[] types)
1088                 {
1089                         return GetProperty (name, DefaultBindingFlags, null, null, types, null);
1090                 }
1091
1092                 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
1093                 {
1094                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
1095                 }
1096
1097                 public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1098                 {
1099                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
1100                 }
1101
1102                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr, Binder binder, Type returnType,
1103                                                  Type[] types, ParameterModifier[] modifiers)
1104                 {
1105                         if (name == null)
1106                                 throw new ArgumentNullException ("name");
1107                         if (types == null)
1108                                 throw new ArgumentNullException ("types");
1109
1110                         foreach (Type t in types) {
1111                                 if (t == null)
1112                                         throw new ArgumentNullException ("types");
1113                         }
1114
1115                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1116                 }
1117
1118                 protected abstract PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
1119                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers);
1120
1121                 internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1122                                                                                                            Type returnType, Type[] types, ParameterModifier[] modifiers)
1123                 {
1124                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1125                 }
1126
1127                 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
1128                                                                        Binder binder,
1129                                                                        CallingConventions callConvention,
1130                                                                        Type[] types,
1131                                                                        ParameterModifier[] modifiers);
1132
1133                 protected abstract TypeAttributes GetAttributeFlagsImpl ();
1134                 protected abstract bool HasElementTypeImpl ();
1135                 protected abstract bool IsArrayImpl ();
1136                 protected abstract bool IsByRefImpl ();
1137                 protected abstract bool IsCOMObjectImpl ();
1138                 protected abstract bool IsPointerImpl ();
1139                 protected abstract bool IsPrimitiveImpl ();
1140                 
1141                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1142                 internal static extern bool IsArrayImpl (Type type);
1143
1144                 protected virtual bool IsValueTypeImpl ()
1145                 {
1146                         if (this == typeof (ValueType) || this == typeof (Enum))
1147                                 return false;
1148
1149                         return IsSubclassOf (typeof (ValueType));
1150                 }
1151                 
1152                 protected virtual bool IsContextfulImpl ()
1153                 {
1154                         return typeof (ContextBoundObject).IsAssignableFrom (this);
1155                 }
1156
1157                 protected virtual bool IsMarshalByRefImpl ()
1158                 {
1159                         return typeof (MarshalByRefObject).IsAssignableFrom (this);
1160                 }
1161
1162                 [ComVisible (true)]
1163                 public ConstructorInfo GetConstructor (Type[] types)
1164                 {
1165                         return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null);
1166                 }
1167
1168                 [ComVisible (true)]
1169                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1170                                                        Type[] types, ParameterModifier[] modifiers)
1171                 {
1172                         return GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers);
1173                 }
1174
1175                 [ComVisible (true)]
1176                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1177                                                        CallingConventions callConvention,
1178                                                        Type[] types, ParameterModifier[] modifiers)
1179                 {
1180                         if (types == null)
1181                                 throw new ArgumentNullException ("types");
1182
1183                         foreach (Type t in types) {
1184                                 if (t == null)
1185                                         throw new ArgumentNullException ("types");
1186                         }
1187
1188                         return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
1189                 }
1190
1191                 [ComVisible (true)]
1192                 public ConstructorInfo[] GetConstructors ()
1193                 {
1194                         return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
1195                 }
1196
1197                 [ComVisible (true)]
1198                 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
1199
1200                 public virtual MemberInfo[] GetDefaultMembers ()
1201                 {
1202                         object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
1203                         if (att.Length == 0)
1204                                 return new MemberInfo [0];
1205
1206                         MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
1207                         return (member != null) ? member : new MemberInfo [0];
1208                 }
1209
1210                 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
1211                                                          MemberFilter filter, object filterCriteria)
1212                 {
1213                         MemberInfo[] result;
1214                         ArrayList l = new ArrayList ();
1215
1216                         // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
1217                         // this.FullName, this.GetType().FullName, this.obj_address());
1218                         if ((memberType & MemberTypes.Method) != 0) {
1219                                 MethodInfo[] c = GetMethods (bindingAttr);
1220                                 if (filter != null) {
1221                                         foreach (MemberInfo m in c) {
1222                                                 if (filter (m, filterCriteria))
1223                                                         l.Add (m);
1224                                         }
1225                                 } else {
1226                                         l.AddRange (c);
1227                                 }
1228                         }
1229                         if ((memberType & MemberTypes.Constructor) != 0) {
1230                                 ConstructorInfo[] c = GetConstructors (bindingAttr);
1231                                 if (filter != null) {
1232                                         foreach (MemberInfo m in c) {
1233                                                 if (filter (m, filterCriteria))
1234                                                         l.Add (m);
1235                                         }
1236                                 } else {
1237                                         l.AddRange (c);
1238                                 }
1239                         }
1240                         if ((memberType & MemberTypes.Property) != 0) {
1241                                 PropertyInfo[] c = GetProperties (bindingAttr);
1242
1243
1244                                 if (filter != null) {
1245                                         foreach (MemberInfo m in c) {
1246                                                 if (filter (m, filterCriteria))
1247                                                         l.Add (m);
1248                                         }
1249                                 } else {
1250                                         l.AddRange (c);
1251                                 }
1252
1253                         }
1254                         if ((memberType & MemberTypes.Event) != 0) {
1255                                 EventInfo[] c = GetEvents (bindingAttr);
1256                                 if (filter != null) {
1257                                         foreach (MemberInfo m in c) {
1258                                                 if (filter (m, filterCriteria))
1259                                                         l.Add (m);
1260                                         }
1261                                 } else {
1262                                         l.AddRange (c);
1263                                 }
1264                         }
1265                         if ((memberType & MemberTypes.Field) != 0) {
1266                                 FieldInfo[] c = GetFields (bindingAttr);
1267                                 if (filter != null) {
1268                                         foreach (MemberInfo m in c) {
1269                                                 if (filter (m, filterCriteria))
1270                                                         l.Add (m);
1271                                         }
1272                                 } else {
1273                                         l.AddRange (c);
1274                                 }
1275                         }
1276                         if ((memberType & MemberTypes.NestedType) != 0) {
1277                                 Type[] c = GetNestedTypes (bindingAttr);
1278                                 if (filter != null) {
1279                                         foreach (MemberInfo m in c) {
1280                                                 if (filter (m, filterCriteria)) {
1281                                                         l.Add (m);
1282                                                 }
1283                                         }
1284                                 } else {
1285                                         l.AddRange (c);
1286                                 }
1287                         }
1288
1289                         switch (memberType) {
1290                         case MemberTypes.Constructor :
1291                                 result = new ConstructorInfo [l.Count];
1292                                 break;
1293                         case MemberTypes.Event :
1294                                 result = new EventInfo [l.Count];
1295                                 break;
1296                         case MemberTypes.Field :
1297                                 result = new FieldInfo [l.Count];
1298                                 break;
1299                         case MemberTypes.Method :
1300                                 result = new MethodInfo [l.Count];
1301                                 break;
1302                         case MemberTypes.NestedType :
1303                         case MemberTypes.TypeInfo :
1304                                 result = new Type [l.Count];
1305                                 break;
1306                         case MemberTypes.Property :
1307                                 result = new PropertyInfo [l.Count];
1308                                 break;
1309                         default :
1310                                 result = new MemberInfo [l.Count];
1311                                 break;
1312                         }
1313                         l.CopyTo (result);
1314                         return result;
1315                 }
1316
1317                 [DebuggerHidden]
1318                 [DebuggerStepThrough] 
1319                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args)
1320                 {
1321                         return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
1322                 }
1323
1324                 [DebuggerHidden]
1325                 [DebuggerStepThrough] 
1326                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
1327                                             object target, object[] args, CultureInfo culture)
1328                 {
1329                         return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
1330                 }
1331
1332                 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
1333                                                      Binder binder, object target, object[] args,
1334                                                      ParameterModifier[] modifiers,
1335                                                      CultureInfo culture, string[] namedParameters);
1336
1337                 public override string ToString()
1338                 {
1339                         return FullName;
1340                 }
1341
1342                 internal virtual bool IsCompilerContext {
1343                         get {
1344                                 AssemblyBuilder builder = Assembly as AssemblyBuilder;
1345                                 return builder != null && builder.IsCompilerContext;
1346                         }
1347                 }
1348
1349                 internal bool IsSystemType {
1350                         get {
1351                                 return _impl.Value != IntPtr.Zero;
1352                         }
1353                 }
1354
1355                 public virtual Type[] GetGenericArguments ()
1356                 {
1357                         throw new NotSupportedException ();
1358                 }
1359
1360                 public virtual bool ContainsGenericParameters {
1361                         get { return false; }
1362                 }
1363
1364                 public virtual extern bool IsGenericTypeDefinition {
1365                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1366                         get;
1367                 }
1368
1369                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1370                 internal extern Type GetGenericTypeDefinition_impl ();
1371
1372                 public virtual Type GetGenericTypeDefinition ()
1373                 {
1374                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1375                 }
1376
1377                 public virtual extern bool IsGenericType {
1378                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1379                         get;
1380                 }
1381
1382                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1383                 static extern Type MakeGenericType (Type gt, Type [] types);
1384
1385                 static AssemblyBuilder PeelAssemblyBuilder (Type type)
1386                 {
1387                         if (type.Assembly is AssemblyBuilder)
1388                                 return (AssemblyBuilder)type.Assembly;
1389
1390                         if (type.HasElementType)
1391                                 return PeelAssemblyBuilder (type.GetElementType ());
1392
1393                         if (!type.IsGenericType || type.IsGenericParameter || type.IsGenericTypeDefinition)
1394                                 return null;
1395
1396                         foreach (Type arg in type.GetGenericArguments ()) {
1397                                 AssemblyBuilder ab = PeelAssemblyBuilder (arg);
1398                                 if (ab != null)
1399                                         return ab;
1400                         }
1401                         return null;
1402                 }
1403
1404                 public virtual Type MakeGenericType (params Type[] typeArguments)
1405                 {
1406                         if (IsUserType)
1407                                 throw new NotSupportedException ();
1408                         if (!IsGenericTypeDefinition)
1409                                 throw new InvalidOperationException ("not a generic type definition");
1410                         if (typeArguments == null)
1411                                 throw new ArgumentNullException ("typeArguments");
1412                         if (GetGenericArguments().Length != typeArguments.Length)
1413                                 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments");
1414
1415                         bool hasUserType = false;
1416                         AssemblyBuilder compilerContext = null;
1417
1418                         Type[] systemTypes = new Type[typeArguments.Length];
1419                         for (int i = 0; i < typeArguments.Length; ++i) {
1420                                 Type t = typeArguments [i];
1421                                 if (t == null)
1422                                         throw new ArgumentNullException ("typeArguments");
1423
1424                                 if (!(t is MonoType))
1425                                         hasUserType = true;
1426                                 if (t.IsCompilerContext)
1427                                         compilerContext = PeelAssemblyBuilder (t);
1428                                 systemTypes [i] = t;
1429                         }
1430
1431                         if (hasUserType) {
1432                                 if (compilerContext != null)
1433                                         return compilerContext.MakeGenericType (this, typeArguments);
1434                                 return new MonoGenericClass (this, typeArguments);
1435                         }
1436
1437                         Type res = MakeGenericType (this, systemTypes);
1438                         if (res == null)
1439                                 throw new TypeLoadException ();
1440                         return res;
1441                 }
1442
1443                 public virtual bool IsGenericParameter {
1444                         get {
1445                                 return false;
1446                         }
1447                 }
1448
1449                 public bool IsNested {
1450                         get {
1451                                 return DeclaringType != null;
1452                         }
1453                 }
1454
1455                 public bool IsVisible {
1456                         get {
1457                                 if (IsNestedPublic)
1458                                         return DeclaringType.IsVisible;
1459
1460                                 return IsPublic;
1461                         }
1462                 }
1463
1464                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1465                 extern int GetGenericParameterPosition ();
1466                 
1467                 public virtual int GenericParameterPosition {
1468                         get {
1469                                 int res = GetGenericParameterPosition ();
1470                                 if (res < 0)
1471                                         throw new InvalidOperationException ();
1472                                 return res;
1473                         }
1474                 }
1475
1476                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1477                 extern GenericParameterAttributes GetGenericParameterAttributes ();
1478
1479                 public virtual GenericParameterAttributes GenericParameterAttributes {
1480                         get {
1481                                 if (!IsSystemType)
1482                                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1483
1484                                 if (!IsGenericParameter)
1485                                         throw new InvalidOperationException ();
1486
1487                                 return GetGenericParameterAttributes ();
1488                         }
1489                 }
1490
1491                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1492                 extern Type[] GetGenericParameterConstraints_impl ();
1493
1494                 public virtual Type[] GetGenericParameterConstraints ()
1495                 {
1496                         if (!IsSystemType)
1497                                 throw new InvalidOperationException ();
1498
1499                         if (!IsGenericParameter)
1500                                 throw new InvalidOperationException ();
1501
1502                         return GetGenericParameterConstraints_impl ();
1503                 }
1504
1505                 public virtual MethodBase DeclaringMethod {
1506                         get {
1507                                 return null;
1508                         }
1509                 }
1510
1511                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1512                 extern Type make_array_type (int rank);
1513
1514                 public virtual Type MakeArrayType ()
1515                 {
1516                         if (!IsSystemType)
1517                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1518                         return make_array_type (0);
1519                 }
1520
1521                 public virtual Type MakeArrayType (int rank)
1522                 {
1523                         if (!IsSystemType)
1524                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1525                         if (rank < 1 || rank > 255)
1526                                 throw new IndexOutOfRangeException ();
1527                         return make_array_type (rank);
1528                 }
1529
1530                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1531                 extern Type make_byref_type ();
1532
1533                 public virtual Type MakeByRefType ()
1534                 {
1535                         if (!IsSystemType)
1536                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1537                         if (IsByRef)
1538                                 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
1539                         return make_byref_type ();
1540                 }
1541
1542                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1543                 static extern Type MakePointerType (Type type);
1544
1545                 public virtual Type MakePointerType ()
1546                 {
1547                         if (!IsSystemType)
1548                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1549                         return MakePointerType (this);
1550                 }
1551
1552                 public static Type ReflectionOnlyGetType (string typeName, 
1553                                                           bool throwIfNotFound, 
1554                                                           bool ignoreCase)
1555                 {
1556                         if (typeName == null)
1557                                 throw new ArgumentNullException ("typeName");
1558                         int idx = typeName.IndexOf (',');
1559                         if (idx < 0 || idx == 0 || idx == typeName.Length - 1)
1560                                 throw new ArgumentException ("Assembly qualifed type name is required", "typeName");
1561                         string an = typeName.Substring (idx + 1);
1562                         Assembly a;
1563                         try {
1564                                 a = Assembly.ReflectionOnlyLoad (an);
1565                         } catch {
1566                                 if (throwIfNotFound)
1567                                         throw;
1568                                 return null;
1569                         }
1570                         return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase);
1571                 }
1572
1573                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1574                 extern void GetPacking (out int packing, out int size);         
1575
1576                 public virtual StructLayoutAttribute StructLayoutAttribute {
1577                         get {
1578                                 LayoutKind kind;
1579
1580                                 if (IsLayoutSequential)
1581                                         kind = LayoutKind.Sequential;
1582                                 else if (IsExplicitLayout)
1583                                         kind = LayoutKind.Explicit;
1584                                 else
1585                                         kind = LayoutKind.Auto;
1586
1587                                 StructLayoutAttribute attr = new StructLayoutAttribute (kind);
1588
1589                                 if (IsUnicodeClass)
1590                                         attr.CharSet = CharSet.Unicode;
1591                                 else if (IsAnsiClass)
1592                                         attr.CharSet = CharSet.Ansi;
1593                                 else
1594                                         attr.CharSet = CharSet.Auto;
1595
1596                                 if (kind != LayoutKind.Auto)
1597                                         GetPacking (out attr.Pack, out attr.Size);
1598
1599                                 return attr;
1600                         }
1601                 }
1602
1603                 internal object[] GetPseudoCustomAttributes ()
1604                 {
1605                         int count = 0;
1606
1607                         /* IsSerializable returns true for delegates/enums as well */
1608                         if ((Attributes & TypeAttributes.Serializable) != 0)
1609                                 count ++;
1610                         if ((Attributes & TypeAttributes.Import) != 0)
1611                                 count ++;
1612
1613                         if (count == 0)
1614                                 return null;
1615                         object[] attrs = new object [count];
1616                         count = 0;
1617
1618                         if ((Attributes & TypeAttributes.Serializable) != 0)
1619                                 attrs [count ++] = new SerializableAttribute ();
1620                         if ((Attributes & TypeAttributes.Import) != 0)
1621                                 attrs [count ++] = new ComImportAttribute ();
1622
1623                         return attrs;
1624                 }                       
1625
1626
1627 #if NET_4_0 || BOOTSTRAP_NET_4_0
1628                 public virtual bool IsEquivalentTo (Type other)
1629                 {
1630                         return this == other;
1631                 }
1632 #endif
1633
1634                 /* 
1635                  * Return whenever this object is an instance of a user defined subclass
1636                  * of System.Type or an instance of TypeDelegator.
1637                  */
1638                 internal bool IsUserType {
1639                         get {
1640                                 /* 
1641                                  * subclasses cannot modify _impl so if it is zero, it means the
1642                                  * type is not created by the runtime.
1643                                  */
1644                                 return _impl.Value == IntPtr.Zero &&
1645                                         (GetType ().Assembly != typeof (Type).Assembly || GetType () == typeof (TypeDelegator));
1646                         }
1647                 }
1648
1649                 void _Type.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1650                 {
1651                         throw new NotImplementedException ();
1652                 }
1653
1654                 void _Type.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1655                 {
1656                         throw new NotImplementedException ();
1657                 }
1658
1659                 void _Type.GetTypeInfoCount (out uint pcTInfo)
1660                 {
1661                         throw new NotImplementedException ();
1662                 }
1663
1664                 void _Type.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1665                 {
1666                         throw new NotImplementedException ();
1667                 }
1668         }
1669 }