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