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