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