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