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