2002-04-03 Nick Drochak <ndrochak@gol.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 // TODO: Mucho left to implement.
10 //
11
12 using System.Reflection;
13 using System.Collections;
14 using System.Runtime.CompilerServices;
15 using System.Globalization;
16
17 namespace System {
18
19         //
20         // FIXME: Implement the various IReflect dependencies
21         //
22
23         [MonoTODO]
24         [Serializable]
25         public abstract class Type : MemberInfo, IReflect {
26                 
27                 internal RuntimeTypeHandle _impl;
28
29                 public static readonly char Delimiter = '.';
30                 public static readonly Type[] EmptyTypes = {};
31                 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
32                 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
33                 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
34                 public static readonly object Missing;
35
36                 /* implementation of the delegates for MemberFilter */
37                 static bool FilterName_impl (MemberInfo m, object filterCriteria) {
38                         string name = (string) filterCriteria;
39                         return name.Equals (m.Name);
40                 }
41                 
42                 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria) {
43                         string name = (string) filterCriteria;
44                         return String.Compare (name, m.Name, true) == 0;
45                 }
46                 
47                 [MonoTODO]
48                 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria) {
49                         throw new NotImplementedException ("FilterAttribute_impl");
50                 }
51
52                 protected Type () {
53                 }
54
55                 /// <summary>
56                 ///   The assembly where the type is defined.
57                 /// </summary>
58                 public abstract Assembly Assembly {
59                         get;
60                 }
61
62                 /// <summary>
63                 ///   Gets the fully qualified name for the type including the
64                 ///   assembly name where the type is defined.
65                 /// </summary>
66                 public abstract string AssemblyQualifiedName {
67                         get;
68                 }
69
70                 /// <summary>
71                 ///   Returns the Attributes associated with the type.
72                 /// </summary>
73                 public TypeAttributes Attributes {
74                         get {
75                                 return GetAttributeFlagsImpl ();
76                         }
77                 }
78                 
79                 /// <summary>
80                 ///   Returns the basetype for this type
81                 /// </summary>
82                 public abstract Type BaseType {
83                         get;
84                 }
85                         
86                 /// <summary>
87                 ///   Returns the class that declares the member.
88                 /// </summary>
89                 [MonoTODO]
90                 public override Type DeclaringType {
91                         get {
92                                 throw new NotImplementedException ();
93                         }
94                 }
95
96                 /// <summary>
97                 ///
98                 /// </summary>
99                 [MonoTODO]
100                 public static Binder DefaultBinder {
101                         get {
102                                 throw new NotImplementedException ();
103                         }
104                 }
105                 
106                 /// <summary>
107                 ///    The full name of the type including its namespace
108                 /// </summary>
109                 public abstract string FullName {
110                         get;
111                 }
112
113                 public abstract Guid GUID {
114                         get;
115                 }
116
117                 [MonoTODO]
118                 public bool HasElementType {
119                         get {return false;} // FIXME
120                 }
121
122                 public bool IsAbstract {
123                         get {
124                                 return (Attributes & TypeAttributes.Abstract) != 0;
125                         }
126                 }
127
128                 public bool IsAnsiClass {
129                         get {
130                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass;
131                         }
132                 }
133
134                 public bool IsArray {
135                         get {
136                                 return IsArrayImpl ();
137                         }
138                 }
139
140                 public bool IsAutoClass {
141                         get {
142                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
143                         }
144                 }
145
146                 public bool IsAutoLayout {
147                         get {
148                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
149                         }
150                 }
151
152                 public bool IsByRef {
153                         get {
154                                 return IsByRefImpl ();
155                         }
156                 }
157
158                 public bool IsClass {
159                         get {
160                                 if (this == typeof (System.Enum) || this == typeof (System.ValueType))
161                                         return true;
162                                 if (IsInterface)
163                                         return false;
164                                 return !type_is_subtype_of (this, typeof (System.ValueType), false);
165                         }
166                 }
167
168                 public bool IsCOMObject {
169                         get {
170                                 return IsCOMObjectImpl ();
171                         }
172                 }
173
174                 public bool IsContextful {
175                         get {
176                                 return IsContextfulImpl ();
177                         }
178                 }
179
180                 public bool IsEnum {
181                         get {
182                                 return type_is_subtype_of (this, typeof (System.Enum), false) &&
183                                         this != typeof (System.Enum);
184                         }
185                 }
186
187                 public bool IsExplicitLayout {
188                         get {
189                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
190                         }
191                 }
192
193                 public bool IsImport {
194                         get {
195                                 return (Attributes & TypeAttributes.Import) != 0;
196                         }
197                 }
198
199                 public bool IsInterface {
200                         get {
201                                 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
202                         }
203                 }
204
205                 public bool IsLayoutSequential {
206                         get {
207                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
208                         }
209                 }
210
211                 public bool IsMarshalByRef {
212                         get {
213                                 return IsMarshalByRefImpl ();
214                         }
215                 }
216
217                 public bool IsNestedAssembly {
218                         get {
219                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
220                         }
221                 }
222
223                 public bool IsNestedFamANDAssem {
224                         get {
225                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
226                         }
227                 }
228
229                 public bool IsNestedFamily {
230                         get {
231                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
232                         }
233                 }
234
235                 public bool IsNestedFamORAssem {
236                         get {
237                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
238                         }
239                 }
240
241                 public bool IsNestedPrivate {
242                         get {
243                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
244                         }
245                 }
246
247                 public bool IsNestedPublic {
248                         get {
249                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
250                         }
251                 }
252
253                 public bool IsNotPublic {
254                         get {
255                                 return !IsPublic;
256                         }
257                 }
258
259                 public bool IsPointer {
260                         get {
261                                 return IsPointerImpl ();
262                         }
263                 }
264
265                 public bool IsPrimitive {
266                         get {
267                                 return IsPrimitiveImpl ();
268                         }
269                 }
270
271                 [MonoTODO]
272                 public bool IsPublic {
273                         get {
274                                 // FIXME: handle nestedpublic, too?
275                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
276                         }
277                 }
278
279                 public bool IsSealed {
280                         get {
281                                 return (Attributes & TypeAttributes.Sealed) != 0;
282                         }
283                 }
284
285                 public bool IsSerializable {
286                         get {
287                                 return (Attributes & TypeAttributes.Serializable) != 0;
288                         }
289                 }
290
291                 public bool IsSpecialName {
292                         get {
293                                 return (Attributes & TypeAttributes.SpecialName) != 0;
294                         }
295                 }
296
297                 public bool IsUnicodeClass {
298                         get {
299                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
300                         }
301                 }
302
303                 public bool IsValueType {
304                         get {
305                                 return IsValueTypeImpl ();
306                         }
307                 }
308
309                 [MonoTODO]
310                 public override MemberTypes MemberType {
311                         get {return MemberTypes.TypeInfo;} // FIXME
312                 }
313
314                 public abstract Module Module {get;}
315         
316                 public abstract string Namespace {get;}
317
318                 [MonoTODO]
319                 public override Type ReflectedType {
320                         get {
321                                 throw new NotImplementedException ();
322                         }
323                 }
324
325                 public abstract RuntimeTypeHandle TypeHandle {get;}
326
327                 [MonoTODO]
328                 public ConstructorInfo TypeInitializer {
329                         get {
330                                 throw new NotImplementedException ();
331                         }
332                 }
333
334                 public abstract Type UnderlyingSystemType {get;}
335
336                 public override bool Equals (object o) {
337                         if (o == null)
338                                 return false;
339                         Type cmp = o as Type;
340                         if (cmp == null)
341                                 return false;
342                         return Equals (cmp);
343                 }
344                 
345                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
346                 public extern bool Equals (Type type);
347                 
348                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
349                 private static extern Type internal_from_handle (RuntimeTypeHandle handle);
350                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
351                 private static extern Type internal_from_name (string name);
352                 
353                 public static Type GetType(string typeName)
354                 {
355                         return internal_from_name (typeName);
356                 }
357
358                 public static Type GetType(string typeName, bool throwOnError)
359                 {
360                         // LAMESPEC: what kinds of errors cause exception to be thrown?
361                         return internal_from_name (typeName);
362                 }
363
364                 [MonoTODO]
365                 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
366                 {
367                         throw new NotImplementedException ();
368                 }
369
370                 public static Type[] GetTypeArray (object[] args) {
371                         Type[] ret;
372
373                         ret = new Type [args.Length];
374                         for (int i = 0; i < args.Length; ++i)
375                                 ret [i] = args[i].GetType ();
376                         return ret;
377                 }
378
379                 [MonoTODO]
380                 public static TypeCode GetTypeCode (Type type)
381                 {
382                         // FIXME -- this is most likely too simplistic for all cases;
383                         //  e.g. Enums
384
385                         Type ust = type.UnderlyingSystemType;
386
387                         if (ust == typeof (Boolean))
388                                 return TypeCode.Boolean;
389                         if (ust == typeof (Byte))
390                                 return TypeCode.Byte;
391                         if (ust == typeof (Char))
392                                 return TypeCode.Char;
393                         if (ust == typeof (DateTime))
394                                 return TypeCode.DateTime;
395                         if (ust == typeof (DBNull))
396                                 return TypeCode.DBNull;
397                         if (ust == typeof (Decimal))
398                                 return TypeCode.Decimal;
399                         if (ust == typeof (Double))
400                                 return TypeCode.Double;
401                         if (ust == typeof (Int16))
402                                 return TypeCode.Int16;
403                         if (ust == typeof (Int32))
404                                 return TypeCode.Int32;
405                         if (ust == typeof (Int64))
406                                 return TypeCode.Int64;
407                         if (ust == typeof (SByte))
408                                 return TypeCode.SByte;
409                         if (ust == typeof (Single))
410                                 return TypeCode.Single;
411                         if (ust == typeof (String))
412                                 return TypeCode.String;
413                         if (ust == typeof (UInt16))
414                                 return TypeCode.UInt16;
415                         if (ust == typeof (UInt32))
416                                 return TypeCode.UInt32;
417                         if (ust == typeof (UInt64))
418                                 return TypeCode.UInt64;
419
420                         return TypeCode.Empty;
421                 }
422
423                 [MonoTODO]
424                 public static Type GetTypeFromCLSID (Guid clsid) {
425                         throw new NotImplementedException ();
426                 }
427
428                 [MonoTODO]
429                 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError) {
430                         throw new NotImplementedException ();
431                 }
432
433                 [MonoTODO]
434                 public static Type GetTypeFromCLSID (Guid clsid, string server) {
435                         throw new NotImplementedException ();
436                 }
437
438                 [MonoTODO]
439                 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError) {
440                         throw new NotImplementedException ();
441                 }
442
443                 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
444                 { 
445                         return internal_from_handle (handle);
446                 }
447
448                 [MonoTODO]
449                 public static Type GetTypeFromProgID (string progID) {
450                         throw new NotImplementedException ();
451                 }
452
453                 [MonoTODO]
454                 public static Type GetTypeFromProgID (string progID, bool throwOnError) {
455                         throw new NotImplementedException ();
456                 }
457
458                 [MonoTODO]
459                 public static Type GetTypeFromProgID (string progID, string server) {
460                         throw new NotImplementedException ();
461                 }
462
463                 [MonoTODO]
464                 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError) {
465                         throw new NotImplementedException ();
466                 }
467
468                 public static RuntimeTypeHandle GetTypeHandle (object o) {
469                         return o.GetType().TypeHandle;
470                 }
471
472                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
473                 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
474                 
475                 public virtual bool IsSubclassOf (Type c)
476                 {
477                         return type_is_subtype_of (this, c, false);
478                 }
479
480                 [MonoTODO]
481                 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
482                 {
483                         // FIXME
484                         throw new NotImplementedException ();
485                 }
486                 
487                 public Type GetInterface (string name) {
488                         return GetInterface (name, false);
489                 }
490
491                 public abstract Type GetInterface (string name, bool ignoreCase);
492
493                 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
494                         throw new NotImplementedException ();
495                 }
496
497                 public abstract Type[] GetInterfaces ();
498
499                 [MonoTODO]
500                 public virtual bool IsAssignableFrom (Type c)
501                 {
502                         // FIXME
503                         return type_is_subtype_of (c, this, true);
504                 }
505
506                 public virtual bool IsInstanceOfType (object o) {
507                         if (o != null) {
508                                 return o.GetType().IsSubclassOf (this);
509                         }
510                         return false;
511                 }
512
513                 [MonoTODO]
514                 public virtual int GetArrayRank ()
515                 {
516                         // FIXME
517                         throw new NotImplementedException ();
518                 }
519
520                 public abstract Type GetElementType ();
521
522                 [MonoTODO]
523                 public EventInfo GetEvent (string name) {
524                         throw new NotImplementedException ();
525                 }
526
527                 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
528
529                 public virtual EventInfo[] GetEvents () {
530                         return GetEvents (BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance);
531                 }
532
533                 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
534
535                 public FieldInfo GetField( string name) {
536                         return GetField (name, BindingFlags.Public);
537                 }
538
539                 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
540
541                 public FieldInfo[] GetFields ()
542                 {
543                         return GetFields (BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static);
544                 }
545
546                 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
547                 
548                 public override int GetHashCode() {
549                         return (int)_impl.Value;
550                 }
551
552                 public MemberInfo[] GetMember( string name) {
553                         return GetMember (name, BindingFlags.Public);
554                 }
555                 
556                 [MonoTODO]
557                 public virtual MemberInfo[] GetMember( string name, BindingFlags bindingAttr) {
558                         // FIXME
559                         throw new NotImplementedException ();
560                 }
561
562                 [MonoTODO]
563                 public virtual MemberInfo[] GetMember( string name, MemberTypes type, BindingFlags bindingAttr) {
564                         // FIXME
565                         throw new NotImplementedException ();
566                 }
567
568                 public MemberInfo[] GetMembers() {
569                         return GetMembers (BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance);
570                 }
571
572                 public abstract MemberInfo[] GetMembers( BindingFlags bindingAttr);
573
574                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
575                 private static extern MethodInfo get_method (Type type, string name, Type[] types);
576
577                 public MethodInfo GetMethod( string name) {
578                         return GetMethod (name, BindingFlags.Public);
579                 }
580
581                 [MonoTODO]
582                 public MethodInfo GetMethod( string name, BindingFlags bindingAttr) {
583                         // FIXME
584                         throw new NotImplementedException ();
585                 }
586                 
587                 public MethodInfo GetMethod (string name, Type[] types)
588                 {
589                         return get_method (this, name, types);
590                 }
591
592                 [MonoTODO]
593                 public MethodInfo GetMethod( string name, Type[] types, ParameterModifier[] modifiers) {
594                         // FIXME
595                         throw new NotImplementedException ();
596                 }
597
598                 [MonoTODO]
599                 public MethodInfo GetMethod( string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) {
600                         // FIXME
601                         throw new NotImplementedException ();
602                 }
603
604                 [MonoTODO]
605                 public MethodInfo GetMethod( string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
606                         // FIXME
607                         throw new NotImplementedException ();
608                 }
609
610                 protected abstract MethodInfo GetMethodImpl( string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
611
612                 public MethodInfo[] GetMethods ()
613                 {
614                         return GetMethods (BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static);
615                 }
616
617                 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
618
619                 public Type GetNestedType( string name) {
620                         return GetNestedType (name, BindingFlags.Public);
621                 }
622
623                 public abstract Type GetNestedType( string name, BindingFlags bindingAttr);
624
625                 public Type[] GetNestedTypes () {
626                         return GetNestedTypes (BindingFlags.Public);
627                 }
628
629                 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
630
631                 public PropertyInfo[] GetProperties ()
632                 {
633                         return GetProperties (BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance);
634                 }
635
636                 public abstract PropertyInfo[] GetProperties( BindingFlags bindingAttr);
637
638                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
639                 private static extern PropertyInfo get_property (Type type, string name, Type[] types);
640                 
641                 public PropertyInfo GetProperty (string name)
642                 {
643                         return GetProperty (name, BindingFlags.Public);
644                 }
645
646                 [MonoTODO]
647                 public PropertyInfo GetProperty( string name, BindingFlags bindingAttr) {
648                         // FIXME
649                         throw new NotImplementedException ();
650                 }
651
652                 [MonoTODO]
653                 public PropertyInfo GetProperty( string name, Type returnType) {
654                         // FIXME
655                         throw new NotImplementedException ();
656                 }
657
658                 public PropertyInfo GetProperty (string name, Type[] types)
659                 {
660                         return get_property (this, name, types);
661                 }
662
663                 [MonoTODO]
664                 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
665                 {
666                         // FIXME
667                         throw new NotImplementedException ();
668                 }
669
670                 [MonoTODO]
671                 public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers) {
672                         // FIXME
673                         throw new NotImplementedException ();
674                 }
675
676                 [MonoTODO]
677                 public PropertyInfo GetProperty( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) {
678                         // FIXME
679                         throw new NotImplementedException ();
680                 }
681
682                 protected abstract PropertyInfo GetPropertyImpl( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
683
684                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
685                 private static extern ConstructorInfo get_constructor (Type type, Type[] types);
686
687                 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
688
689                 protected abstract TypeAttributes GetAttributeFlagsImpl ();
690                 protected abstract bool HasElementTypeImpl ();
691                 protected abstract bool IsArrayImpl ();
692                 protected abstract bool IsByRefImpl ();
693                 protected abstract bool IsCOMObjectImpl ();
694                 protected virtual bool IsContextfulImpl () {
695                         return typeof (ContextBoundObject).IsAssignableFrom (this);
696                 }
697                 [MonoTODO]
698                 protected virtual bool IsMarshalByRefImpl () {
699                         // FIXME
700                         return false;
701                 }
702                 protected abstract bool IsPointerImpl ();
703                 protected abstract bool IsPrimitiveImpl ();
704                 protected abstract bool IsValueTypeImpl ();
705                 
706                 public ConstructorInfo GetConstructor (Type[] types)
707                 {
708                         return get_constructor (this, types);
709                 }
710
711                 [MonoTODO]
712                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) {
713                         throw new NotImplementedException ();
714                 }
715
716                 [MonoTODO]
717                 public ConstructorInfo GetConstructor( BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
718                         throw new NotImplementedException ();
719                 }
720
721                 public ConstructorInfo[] GetConstructors () {
722                         return GetConstructors (BindingFlags.Public|BindingFlags.Static|BindingFlags.Instance);
723                 }
724                 
725                 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
726
727                 [MonoTODO]
728                 public virtual MemberInfo[] GetDefaultMembers () {
729                         throw new NotImplementedException ();
730                 }
731
732                 public virtual MemberInfo[] FindMembers( MemberTypes memberType, BindingFlags bindingAttr,
733                                                          MemberFilter filter, object filterCriteria) {
734                         MemberInfo[] result;
735                         ArrayList l = new ArrayList ();
736
737                         //Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}", this.FullName, this.GetType().FullName, this.obj_address());
738
739                         if ((memberType & MemberTypes.Constructor) != 0) {
740                                 ConstructorInfo[] c = GetConstructors (bindingAttr);
741                                 if (filter != null) {
742                                         foreach (MemberInfo m in c) {
743                                                 if (filter (m, filterCriteria))
744                                                         l.Add (m);
745                                         }
746                                 } else {
747                                         l.AddRange (c);
748                                 }
749                         }
750                         if ((memberType & MemberTypes.Event) != 0) {
751                                 EventInfo[] c = GetEvents (bindingAttr);
752                                 if (filter != null) {
753                                         foreach (MemberInfo m in c) {
754                                                 if (filter (m, filterCriteria))
755                                                         l.Add (m);
756                                         }
757                                 } else {
758                                         l.AddRange (c);
759                                 }
760                         }
761                         if ((memberType & MemberTypes.Field) != 0) {
762                                 FieldInfo[] c = GetFields (bindingAttr);
763                                 if (filter != null) {
764                                         foreach (MemberInfo m in c) {
765                                                 if (filter (m, filterCriteria))
766                                                         l.Add (m);
767                                         }
768                                 } else {
769                                         l.AddRange (c);
770                                 }
771                         }
772                         if ((memberType & MemberTypes.Method) != 0) {
773                                 MethodInfo[] c = GetMethods (bindingAttr);
774                                 if (filter != null) {
775                                         foreach (MemberInfo m in c) {
776                                                 if (filter (m, filterCriteria))
777                                                         l.Add (m);
778                                         }
779                                 } else {
780                                         l.AddRange (c);
781                                 }
782                         }
783                         if ((memberType & MemberTypes.Property) != 0) {
784                                 PropertyInfo[] c;
785                                 int count = l.Count;
786                                 Type ptype;
787                                 if (filter != null) {
788                                         ptype = this;
789                                         while ((l.Count == count) && (ptype != null)) {
790                                                 c = ptype.GetProperties (bindingAttr);
791                                                 foreach (MemberInfo m in c) {
792                                                         if (filter (m, filterCriteria))
793                                                                 l.Add (m);
794                                                 }
795                                                 ptype = ptype.BaseType;
796                                         }
797                                 } else {
798                                         c = GetProperties (bindingAttr);
799                                         l.AddRange (c);
800                                 }
801                         }
802                         result = new MemberInfo [l.Count];
803                         l.CopyTo (result);
804                         return result;
805                 }
806
807                 [MonoTODO]
808                 public object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) {
809                         // FIXME
810                         return null;
811                 }
812
813                 [MonoTODO]
814                 public object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture) {
815                         // FIXME
816                         return null;
817                 }
818
819                 public abstract object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
820
821                 public override string ToString()
822                 {
823                         string res = FullName;
824                         if (IsArray)
825                                 res = res + "[]";
826                         if (IsByRef)
827                                 res = res + "&";
828                         if (IsPointer)
829                                 res = res + "*";
830                         return res;
831                 }
832         }
833 }