Wed Mar 5 19:39:01 CET 2008 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 #if NET_2_0
46         [ComVisible (true)]
47         [ComDefaultInterface (typeof (_Type))]
48 #endif
49         public abstract class Type : MemberInfo, IReflect, _Type, _MemberInfo {
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                 public abstract Type UnderlyingSystemType {get;}
417
418                 public override bool Equals (object o)
419                 {
420                         if (o == null)
421                                 return false;
422                         
423                         Type cmp = o as Type;
424                         if (cmp == null)
425                                 return false;
426                         return Equals (cmp);
427                 }
428
429                 public bool Equals (Type type) {
430                         if (type == null)
431                                 return false;
432                         return UnderlyingSystemType.EqualsInternal (type.UnderlyingSystemType);
433                 }
434
435                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
436                 internal extern bool EqualsInternal (Type type);
437                 
438                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
439                 private static extern Type internal_from_handle (IntPtr handle);
440                 
441                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
442                 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
443
444                 public static Type GetType(string typeName)
445                 {
446                         if (typeName == null)
447                                 throw new ArgumentNullException ("typeName");
448
449                         return internal_from_name (typeName, false, false);
450                 }
451
452                 public static Type GetType(string typeName, bool throwOnError)
453                 {
454                         if (typeName == null)
455                                 throw new ArgumentNullException ("typeName");
456
457                         Type type = internal_from_name (typeName, throwOnError, false);
458                         if (throwOnError && type == null)
459                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
460
461                         return type;
462                 }
463
464                 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
465                 {
466                         if (typeName == null)
467                                 throw new ArgumentNullException ("typeName");
468
469                         Type t = internal_from_name (typeName, throwOnError, ignoreCase);
470                         if (throwOnError && t == null)
471                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
472
473                         return t;
474                 }
475
476                 public static Type[] GetTypeArray (object[] args) {
477                         if (args == null)
478                                 throw new ArgumentNullException ("args");
479
480                         Type[] ret;
481                         ret = new Type [args.Length];
482                         for (int i = 0; i < args.Length; ++i)
483                                 ret [i] = args[i].GetType ();
484                         return ret;
485                 }
486
487                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
488                 internal extern static TypeCode GetTypeCodeInternal (Type type);
489
490                 public static TypeCode GetTypeCode (Type type) {
491                         if (type is MonoType)
492                                 return GetTypeCodeInternal (type);
493                         if (type == null)
494                                 /* MS.NET returns this */
495                                 return TypeCode.Empty;
496
497                         type = type.UnderlyingSystemType;
498
499                         if (!type.IsSystemType)
500                                 return TypeCode.Object;
501                         else
502                                 return GetTypeCodeInternal (type);
503                 }
504
505                 [MonoTODO("Mono does not support COM")]
506                 public static Type GetTypeFromCLSID (Guid clsid)
507                 {
508                         throw new NotImplementedException ();
509                 }
510
511                 [MonoTODO("Mono does not support COM")]
512                 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
513                 {
514                         throw new NotImplementedException ();
515                 }
516
517                 [MonoTODO("Mono does not support COM")]
518                 public static Type GetTypeFromCLSID (Guid clsid, string server)
519                 {
520                         throw new NotImplementedException ();
521                 }
522
523                 [MonoTODO("Mono does not support COM")]
524                 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
525                 {
526                         throw new NotImplementedException ();
527                 }
528
529                 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
530                 { 
531                         return internal_from_handle (handle.Value);
532                 }
533
534                 [MonoTODO("Mono does not support COM")]
535                 public static Type GetTypeFromProgID (string progID)
536                 {
537                         throw new NotImplementedException ();
538                 }
539
540                 [MonoTODO("Mono does not support COM")]
541                 public static Type GetTypeFromProgID (string progID, bool throwOnError)
542                 {
543                         throw new NotImplementedException ();
544                 }
545
546                 [MonoTODO("Mono does not support COM")]
547                 public static Type GetTypeFromProgID (string progID, string server)
548                 {
549                         throw new NotImplementedException ();
550                 }
551
552                 [MonoTODO("Mono does not support COM")]
553                 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
554                 {
555                         throw new NotImplementedException ();
556                 }
557
558                 public static RuntimeTypeHandle GetTypeHandle (object o)
559                 {
560                         return o.GetType().TypeHandle;
561                 }
562
563                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
564                 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
565
566                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
567                 internal static extern bool type_is_assignable_from (Type a, Type b);
568
569                 public new Type GetType ()
570                 {
571                         return base.GetType ();
572                 }
573
574 #if NET_2_0
575                 [ComVisible (true)]
576 #endif
577                 public virtual bool IsSubclassOf (Type c)
578                 {
579                         if (c == null || c == this)
580                                 return false;
581
582                         // Fast check for system types
583                         if (IsSystemType)
584                                 return c.IsSystemType && type_is_subtype_of (this, c, false);
585
586                         // User defined types depend on this behavior
587                         for (Type type = BaseType; type != null; type = type.BaseType)
588                                 if (type == c)
589                                         return true;
590
591                         return false;
592                 }
593
594                 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
595                 {
596                         if (filter == null)
597                                 throw new ArgumentNullException ("filter");
598
599                         ArrayList ifaces = new ArrayList ();
600                         foreach (Type iface in GetInterfaces ()) {
601                                 if (filter (iface, filterCriteria))
602                                         ifaces.Add (iface);
603                         }
604
605                         return (Type []) ifaces.ToArray (typeof (Type));
606                 }
607                 
608                 public Type GetInterface (string name) {
609                         return GetInterface (name, false);
610                 }
611
612                 public abstract Type GetInterface (string name, bool ignoreCase);
613
614                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
615                 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
616
617 #if NET_2_0
618                 [ComVisible (true)]
619 #endif          
620                 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
621                         InterfaceMapping res;
622                         if (interfaceType == null)
623                                 throw new ArgumentNullException ("interfaceType");
624                         if (!interfaceType.IsInterface)
625                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType");
626                         res.TargetType = this;
627                         res.InterfaceType = interfaceType;
628                         GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
629                         if (res.TargetMethods == null)
630                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType");
631
632                         return res;
633                 }
634
635                 public abstract Type[] GetInterfaces ();
636
637                 public virtual bool IsAssignableFrom (Type c)
638                 {
639                         if (c == null)
640                                 return false;
641
642                         if (Equals (c))
643                                 return true;
644
645                         if (c is TypeBuilder)
646                                 return ((TypeBuilder)c).IsAssignableTo (this);
647
648                         /* Handle user defined type classes */
649                         if (!IsSystemType) {
650                                 Type systemType = UnderlyingSystemType;
651                                 if (!systemType.IsSystemType)
652                                         return false;
653                                 return systemType.IsAssignableFrom (c);
654                         }
655
656                         if (!c.IsSystemType) {
657                                 Type underlyingType = c.UnderlyingSystemType;
658                                 if (!underlyingType.IsSystemType)
659                                         return false;
660                                 return IsAssignableFrom (underlyingType);
661                         }
662
663                         return type_is_assignable_from (this, c);
664                 }
665
666                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
667                 public extern virtual bool IsInstanceOfType (object o);
668
669                 public virtual int GetArrayRank ()
670                 {
671                         throw new NotSupportedException ();     // according to MSDN
672                 }
673
674                 public abstract Type GetElementType ();
675
676                 public EventInfo GetEvent (string name)
677                 {
678                         return GetEvent (name, DefaultBindingFlags);
679                 }
680
681                 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
682
683                 public virtual EventInfo[] GetEvents ()
684                 {
685                         return GetEvents (DefaultBindingFlags);
686                 }
687
688                 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
689
690                 public FieldInfo GetField( string name)
691                 {
692                         return GetField (name, DefaultBindingFlags);
693                 }
694
695                 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
696
697                 public FieldInfo[] GetFields ()
698                 {
699                         return GetFields (DefaultBindingFlags);
700                 }
701
702                 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
703                 
704                 public override int GetHashCode()
705                 {
706                         return (int)_impl.Value;
707                 }
708
709                 public MemberInfo[] GetMember (string name)
710                 {
711                         return GetMember (name, DefaultBindingFlags);
712                 }
713                 
714                 public virtual MemberInfo[] GetMember (string name, BindingFlags bindingAttr)
715                 {
716                         return GetMember (name, MemberTypes.All, bindingAttr);
717                 }
718
719                 public virtual MemberInfo[] GetMember (string name, MemberTypes type, BindingFlags bindingAttr)
720                 {
721                         if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
722                                 return FindMembers (type, bindingAttr, FilterNameIgnoreCase, name);
723                         else
724                                 return FindMembers (type, bindingAttr, FilterName, name);
725                 }
726
727                 public MemberInfo[] GetMembers ()
728                 {
729                         return GetMembers (DefaultBindingFlags);
730                 }
731
732                 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
733
734                 public MethodInfo GetMethod (string name)
735                 {
736                         if (name == null)
737                                 throw new ArgumentNullException ("name");
738                         return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
739                 }
740
741                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
742                 {
743                         if (name == null)
744                                 throw new ArgumentNullException ("name");
745                         
746                         return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
747                 }
748                 
749                 public MethodInfo GetMethod (string name, Type[] types)
750                 {
751                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
752                 }
753
754                 public MethodInfo GetMethod (string name, Type[] types, ParameterModifier[] modifiers)
755                 {
756                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, modifiers);
757                 }
758
759                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
760                                              Type[] types, ParameterModifier[] modifiers)
761                 {
762                         
763                         return GetMethod (name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
764                 }
765
766                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
767                                              CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
768                 {
769                         if (name == null)
770                                 throw new ArgumentNullException ("name");
771                         if (types == null)
772                                 throw new ArgumentNullException ("types");
773
774                         for (int i = 0; i < types.Length; i++) 
775                                 if (types[i] == null)
776                                         throw new ArgumentNullException ("types");
777
778                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
779                 }
780
781                 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
782                                                              CallingConventions callConvention, Type[] types,
783                                                              ParameterModifier[] modifiers);
784
785                 internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder,
786                                                                                                                         CallingConventions callConvention, Type[] types,
787                                                                                                                         ParameterModifier[] modifiers)
788                 {
789                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
790                 }
791
792                 internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated)
793                 {
794                         throw new System.InvalidOperationException ("can only be called in generic type");
795                 }
796
797                 internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
798                 {
799                         throw new System.InvalidOperationException ("can only be called in generic type");
800                 }
801
802                 internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated)
803                 {
804                         throw new System.InvalidOperationException ("can only be called in generic type");
805                 }
806
807                 
808                 public MethodInfo[] GetMethods ()
809                 {
810                         return GetMethods (DefaultBindingFlags);
811                 }
812
813                 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
814
815                 public Type GetNestedType (string name)
816                 {
817                         return GetNestedType (name, DefaultBindingFlags);
818                 }
819
820                 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
821
822                 public Type[] GetNestedTypes ()
823                 {
824                         return GetNestedTypes (DefaultBindingFlags);
825                 }
826
827                 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
828
829
830                 public PropertyInfo[] GetProperties ()
831                 {
832                         return GetProperties (DefaultBindingFlags);
833                 }
834
835                 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
836
837
838                 public PropertyInfo GetProperty (string name)
839                 {
840                         if (name == null)
841                                 throw new ArgumentNullException ("name");
842
843                         return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null);
844                 }
845
846                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
847                 {
848                         if (name == null)
849                                 throw new ArgumentNullException ("name");
850                         return GetPropertyImpl (name, bindingAttr, null, null, null, null);
851                 }
852
853                 public PropertyInfo GetProperty (string name, Type returnType)
854                 {
855                         if (name == null)
856                                 throw new ArgumentNullException ("name");
857                         return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null);
858                 }
859
860                 public PropertyInfo GetProperty (string name, Type[] types)
861                 {
862                         return GetProperty (name, DefaultBindingFlags, null, null, types, null);
863                 }
864
865                 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
866                 {
867                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
868                 }
869
870                 public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
871                 {
872                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
873                 }
874
875                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr, Binder binder, Type returnType,
876                                                  Type[] types, ParameterModifier[] modifiers)
877                 {
878                         if (name == null)
879                                 throw new ArgumentNullException ("name");
880                         if (types == null)
881                                 throw new ArgumentNullException ("types");
882
883                         foreach (Type t in types) {
884                                 if (t == null)
885                                         throw new ArgumentNullException ("types");
886                         }
887
888                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
889                 }
890
891                 protected abstract PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
892                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers);
893
894                 internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder,
895                                                                                                            Type returnType, Type[] types, ParameterModifier[] modifiers)
896                 {
897                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
898                 }
899
900                 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
901                                                                        Binder binder,
902                                                                        CallingConventions callConvention,
903                                                                        Type[] types,
904                                                                        ParameterModifier[] modifiers);
905
906                 protected abstract TypeAttributes GetAttributeFlagsImpl ();
907                 protected abstract bool HasElementTypeImpl ();
908                 protected abstract bool IsArrayImpl ();
909                 protected abstract bool IsByRefImpl ();
910                 protected abstract bool IsCOMObjectImpl ();
911                 protected abstract bool IsPointerImpl ();
912                 protected abstract bool IsPrimitiveImpl ();
913                 
914                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
915                 internal static extern bool IsArrayImpl (Type type);
916
917                 protected virtual bool IsValueTypeImpl ()
918                 {
919                         if (this == typeof (ValueType) || this == typeof (Enum))
920                                 return false;
921
922                         return IsSubclassOf (typeof (ValueType));
923                 }
924                 
925                 protected virtual bool IsContextfulImpl ()
926                 {
927                         return typeof (ContextBoundObject).IsAssignableFrom (this);
928                 }
929
930                 protected virtual bool IsMarshalByRefImpl ()
931                 {
932                         return typeof (MarshalByRefObject).IsAssignableFrom (this);
933                 }
934
935 #if NET_2_0
936                 [ComVisible (true)]
937 #endif
938                 public ConstructorInfo GetConstructor (Type[] types)
939                 {
940                         return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null);
941                 }
942
943 #if NET_2_0
944                 [ComVisible (true)]
945 #endif
946                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
947                                                        Type[] types, ParameterModifier[] modifiers)
948                 {
949                         return GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers);
950                 }
951
952 #if NET_2_0
953                 [ComVisible (true)]
954 #endif
955                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
956                                                        CallingConventions callConvention,
957                                                        Type[] types, ParameterModifier[] modifiers)
958                 {
959                         if (types == null)
960                                 throw new ArgumentNullException ("types");
961
962                         foreach (Type t in types) {
963                                 if (t == null)
964                                         throw new ArgumentNullException ("types");
965                         }
966
967                         return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
968                 }
969
970 #if NET_2_0
971                 [ComVisible (true)]
972 #endif
973                 public ConstructorInfo[] GetConstructors ()
974                 {
975                         return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
976                 }
977
978 #if NET_2_0
979                 [ComVisible (true)]
980 #endif          
981                 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
982
983                 public virtual MemberInfo[] GetDefaultMembers ()
984                 {
985                         object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
986                         if (att.Length == 0)
987                                 return new MemberInfo [0];
988
989                         MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
990                         return (member != null) ? member : new MemberInfo [0];
991                 }
992
993                 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
994                                                          MemberFilter filter, object filterCriteria)
995                 {
996                         MemberInfo[] result;
997                         ArrayList l = new ArrayList ();
998
999                         // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
1000                         // this.FullName, this.GetType().FullName, this.obj_address());
1001
1002                         if ((memberType & MemberTypes.Constructor) != 0) {
1003                                 ConstructorInfo[] c = GetConstructors (bindingAttr);
1004                                 if (filter != null) {
1005                                         foreach (MemberInfo m in c) {
1006                                                 if (filter (m, filterCriteria))
1007                                                         l.Add (m);
1008                                         }
1009                                 } else {
1010                                         l.AddRange (c);
1011                                 }
1012                         }
1013                         if ((memberType & MemberTypes.Event) != 0) {
1014                                 EventInfo[] c = GetEvents (bindingAttr);
1015                                 if (filter != null) {
1016                                         foreach (MemberInfo m in c) {
1017                                                 if (filter (m, filterCriteria))
1018                                                         l.Add (m);
1019                                         }
1020                                 } else {
1021                                         l.AddRange (c);
1022                                 }
1023                         }
1024                         if ((memberType & MemberTypes.Field) != 0) {
1025                                 FieldInfo[] c = GetFields (bindingAttr);
1026                                 if (filter != null) {
1027                                         foreach (MemberInfo m in c) {
1028                                                 if (filter (m, filterCriteria))
1029                                                         l.Add (m);
1030                                         }
1031                                 } else {
1032                                         l.AddRange (c);
1033                                 }
1034                         }
1035                         if ((memberType & MemberTypes.Method) != 0) {
1036                                 MethodInfo[] c = GetMethods (bindingAttr);
1037                                 if (filter != null) {
1038                                         foreach (MemberInfo m in c) {
1039                                                 if (filter (m, filterCriteria))
1040                                                         l.Add (m);
1041                                         }
1042                                 } else {
1043                                         l.AddRange (c);
1044                                 }
1045                         }
1046                         if ((memberType & MemberTypes.Property) != 0) {
1047                                 PropertyInfo[] c;
1048                                 int count = l.Count;
1049                                 Type ptype;
1050                                 if (filter != null) {
1051                                         ptype = this;
1052                                         while ((l.Count == count) && (ptype != null)) {
1053                                                 c = ptype.GetProperties (bindingAttr);
1054                                                 foreach (MemberInfo m in c) {
1055                                                         if (filter (m, filterCriteria))
1056                                                                 l.Add (m);
1057                                                 }
1058                                                 ptype = ptype.BaseType;
1059                                         }
1060                                 } else {
1061                                         c = GetProperties (bindingAttr);
1062                                         l.AddRange (c);
1063                                 }
1064                         }
1065                         if ((memberType & MemberTypes.NestedType) != 0) {
1066                                 Type[] c = GetNestedTypes (bindingAttr);
1067                                 if (filter != null) {
1068                                         foreach (MemberInfo m in c) {
1069                                                 if (filter (m, filterCriteria)) {
1070                                                         l.Add (m);
1071                                                 }
1072                                         }
1073                                 } else {
1074                                         l.AddRange (c);
1075                                 }
1076                         }
1077                         result = new MemberInfo [l.Count];
1078                         l.CopyTo (result);
1079                         return result;
1080                 }
1081
1082                 [DebuggerHidden]
1083                 [DebuggerStepThrough] 
1084                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args)
1085                 {
1086                         return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
1087                 }
1088
1089                 [DebuggerHidden]
1090                 [DebuggerStepThrough] 
1091                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
1092                                             object target, object[] args, CultureInfo culture)
1093                 {
1094                         return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
1095                 }
1096
1097                 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
1098                                                      Binder binder, object target, object[] args,
1099                                                      ParameterModifier[] modifiers,
1100                                                      CultureInfo culture, string[] namedParameters);
1101
1102                 public override string ToString()
1103                 {
1104                         return FullName;
1105                 }
1106
1107                 internal bool IsSystemType {
1108                         get {
1109                                 return _impl.Value != IntPtr.Zero;
1110                         }
1111                 }
1112
1113 #if NET_2_0 || BOOTSTRAP_NET_2_0
1114                 public virtual Type[] GetGenericArguments ()
1115                 {
1116                         throw new NotSupportedException ();
1117                 }
1118
1119                 public virtual bool ContainsGenericParameters {
1120                         get { return false; }
1121                 }
1122
1123                 public virtual extern bool IsGenericTypeDefinition {
1124                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1125                         get;
1126                 }
1127
1128                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1129                 extern Type GetGenericTypeDefinition_impl ();
1130
1131                 public virtual Type GetGenericTypeDefinition ()
1132                 {
1133                         Type res = GetGenericTypeDefinition_impl ();
1134                         if (res == null)
1135                                 throw new InvalidOperationException ();
1136
1137                         return res;
1138                 }
1139
1140                 public virtual extern bool IsGenericType {
1141                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1142                         get;
1143                 }
1144
1145                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1146                 static extern Type MakeGenericType (Type gt, Type [] types);
1147
1148                 public virtual Type MakeGenericType (params Type[] types)
1149                 {
1150                         if (!IsGenericTypeDefinition)
1151                                 throw new InvalidOperationException ("not a generic type definition");
1152                         if (types == null)
1153                                 throw new ArgumentNullException ("types");
1154                         if (GetGenericArguments().Length != types.Length)
1155                                 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, types.Length), "types");
1156
1157                         Type[] systemTypes = new Type[types.Length];
1158                         for (int i = 0; i < types.Length; ++i) {
1159                                 Type t = types [i];
1160                                 if (t == null)
1161                                         throw new ArgumentNullException ("types");
1162
1163                                 t = t.UnderlyingSystemType;
1164                                 if (t == null || !t.IsSystemType)
1165                                         throw new ArgumentNullException ("types");
1166                                 systemTypes [i] = types [i].UnderlyingSystemType;
1167                         }
1168
1169                         Type res = MakeGenericType (this, systemTypes);
1170                         if (res == null)
1171                                 throw new TypeLoadException ();
1172                         return res;
1173                 }
1174
1175                 public virtual bool IsGenericParameter {
1176                         get {
1177                                 return false;
1178                         }
1179                 }
1180
1181                 public bool IsNested {
1182                         get {
1183                                 return DeclaringType != null;
1184                         }
1185                 }
1186
1187                 public bool IsVisible {
1188                         get {
1189                                 if (IsNestedPublic)
1190                                         return DeclaringType.IsVisible;
1191
1192                                 return IsPublic;
1193                         }
1194                 }
1195
1196                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1197                 extern int GetGenericParameterPosition ();
1198                 
1199                 public virtual int GenericParameterPosition {
1200                         get {
1201                                 int res = GetGenericParameterPosition ();
1202                                 if (res < 0)
1203                                         throw new InvalidOperationException ();
1204                                 return res;
1205                         }
1206                 }
1207
1208                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1209                 extern GenericParameterAttributes GetGenericParameterAttributes ();
1210
1211                 public virtual GenericParameterAttributes GenericParameterAttributes {
1212                         get {
1213                                 if (!IsGenericParameter)
1214                                         throw new InvalidOperationException ();
1215
1216                                 return GetGenericParameterAttributes ();
1217                         }
1218                 }
1219
1220                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1221                 extern Type[] GetGenericParameterConstraints_impl ();
1222
1223                 public virtual Type[] GetGenericParameterConstraints ()
1224                 {
1225                         if (!IsGenericParameter)
1226                                 throw new InvalidOperationException ();
1227
1228                         return GetGenericParameterConstraints_impl ();
1229                 }
1230
1231                 public virtual MethodBase DeclaringMethod {
1232                         get {
1233                                 return null;
1234                         }
1235                 }
1236
1237                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1238                 extern Type make_array_type (int rank);
1239
1240                 public virtual Type MakeArrayType ()
1241                 {
1242                         return MakeArrayType (1);
1243                 }
1244
1245                 public virtual Type MakeArrayType (int rank)
1246                 {
1247                         if (rank < 1)
1248                                 throw new IndexOutOfRangeException ();
1249                         return make_array_type (rank);
1250                 }
1251
1252                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1253                 extern Type make_byref_type ();
1254
1255                 public virtual Type MakeByRefType ()
1256                 {
1257                         return make_byref_type ();
1258                 }
1259
1260                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1261                 public extern virtual Type MakePointerType ();
1262
1263                 public static Type ReflectionOnlyGetType (string typeName, 
1264                                                           bool throwIfNotFound, 
1265                                                           bool ignoreCase)
1266                 {
1267                         if (typeName == null)
1268                                 throw new ArgumentNullException ("typeName");
1269                         int idx = typeName.IndexOf (',');
1270                         if (idx < 0 || idx == 0 || idx == typeName.Length - 1)
1271                                 throw new ArgumentException ("Assembly qualifed type name is required", "typeName");
1272                         string an = typeName.Substring (idx + 1);
1273                         Assembly a;
1274                         try {
1275                                 a = Assembly.ReflectionOnlyLoad (an);
1276                         } catch {
1277                                 if (throwIfNotFound)
1278                                         throw;
1279                                 return null;
1280                         }
1281                         return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase);
1282                 }
1283
1284                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1285                 extern void GetPacking (out int packing, out int size);         
1286
1287                 public virtual StructLayoutAttribute StructLayoutAttribute {
1288                         get {
1289                                 LayoutKind kind;
1290
1291                                 if (IsLayoutSequential)
1292                                         kind = LayoutKind.Sequential;
1293                                 else if (IsExplicitLayout)
1294                                         kind = LayoutKind.Explicit;
1295                                 else
1296                                         kind = LayoutKind.Auto;
1297
1298                                 StructLayoutAttribute attr = new StructLayoutAttribute (kind);
1299
1300                                 if (IsUnicodeClass)
1301                                         attr.CharSet = CharSet.Unicode;
1302                                 else if (IsAnsiClass)
1303                                         attr.CharSet = CharSet.Ansi;
1304                                 else
1305                                         attr.CharSet = CharSet.Auto;
1306
1307                                 if (kind != LayoutKind.Auto)
1308                                         GetPacking (out attr.Pack, out attr.Size);
1309
1310                                 return attr;
1311                         }
1312                 }
1313
1314                 internal object[] GetPseudoCustomAttributes ()
1315                 {
1316                         int count = 0;
1317
1318                         /* IsSerializable returns true for delegates/enums as well */
1319                         if ((Attributes & TypeAttributes.Serializable) != 0)
1320                                 count ++;
1321                         if ((Attributes & TypeAttributes.Import) != 0)
1322                                 count ++;
1323
1324                         if (count == 0)
1325                                 return null;
1326                         object[] attrs = new object [count];
1327                         count = 0;
1328
1329                         if ((Attributes & TypeAttributes.Serializable) != 0)
1330                                 attrs [count ++] = new SerializableAttribute ();
1331                         if ((Attributes & TypeAttributes.Import) != 0)
1332                                 attrs [count ++] = new ComImportAttribute ();
1333
1334                         return attrs;
1335                 }                       
1336
1337 #endif
1338
1339                 void _Type.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1340                 {
1341                         throw new NotImplementedException ();
1342                 }
1343
1344                 void _Type.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1345                 {
1346                         throw new NotImplementedException ();
1347                 }
1348
1349                 void _Type.GetTypeInfoCount (out uint pcTInfo)
1350                 {
1351                         throw new NotImplementedException ();
1352                 }
1353
1354                 void _Type.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1355                 {
1356                         throw new NotImplementedException ();
1357                 }
1358         }
1359 }