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