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