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