e31567473f76028d20434e8ef3e53f23aab793bb
[mono.git] / mcs / class / referencesource / mscorlib / system / type.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 //
7 // File: Type.cs
8 //
9 // <OWNER>[....]</OWNER>
10 //
11 // Implements System.Type
12 //
13 // ======================================================================================
14
15 namespace System {
16
17     using System;
18     using System.Reflection;
19     using System.Threading;
20     using System.Runtime;
21     using System.Runtime.Remoting;
22     using System.Runtime.InteropServices;
23     using System.Runtime.CompilerServices;
24     using System.Security;
25     using System.Security.Permissions;
26     using System.Collections;
27     using System.Collections.Generic;
28     using System.Runtime.Versioning;
29     using System.Diagnostics.Contracts;
30     using CultureInfo = System.Globalization.CultureInfo;
31     using StackCrawlMark = System.Threading.StackCrawlMark;
32     using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
33
34     [Serializable]
35     [ClassInterface(ClassInterfaceType.None)]
36     [ComDefaultInterface(typeof(_Type))]
37     [System.Runtime.InteropServices.ComVisible(true)]
38 #if CONTRACTS_FULL
39     [ContractClass(typeof(TypeContracts))]
40 #endif
41     public abstract partial class Type : MemberInfo, _Type, IReflect
42     {
43         //
44         // System.Type is appdomain agile type. Appdomain agile types cannot have precise static constructors. Make
45         // sure to never introduce one here!
46         //
47         public static readonly MemberFilter FilterAttribute = new MemberFilter(__Filters.Instance.FilterAttribute);
48         public static readonly MemberFilter FilterName = new MemberFilter(__Filters.Instance.FilterName);
49         public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter(__Filters.Instance.FilterIgnoreCase);
50
51         public static readonly Object Missing = System.Reflection.Missing.Value;
52
53         public static readonly char Delimiter = '.'; 
54
55         // EmptyTypes is used to indicate that we are looking for someting without any parameters.
56         public readonly static Type[] EmptyTypes = EmptyArray<Type>.Value;
57
58         // The Default binder.  We create a single one and expose that.
59         private static Binder defaultBinder;
60
61
62         protected Type() {}        
63
64
65         // MemberInfo Methods....
66         // The Member type Field.
67         public override MemberTypes MemberType {
68             get {return System.Reflection.MemberTypes.TypeInfo;}
69         }
70
71         // Return the class that declared this type.
72         public override Type DeclaringType {
73             get {return null;}
74         }
75
76         public virtual MethodBase DeclaringMethod { get { return null; } }
77
78         // Return the class that was used to obtain this type.
79         public override Type ReflectedType
80         {
81             get {return null;}
82         }
83
84         ////////////////////////////////////////////////////////////////////////////////
85         // This is a static method that returns a Class based upon the name of the class
86         // (this name needs to be fully qualified with the package name and is
87         // case-sensitive by default).
88         ////  
89
90 #if !MONO
91         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
92         public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) {
93             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
94             return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
95         }
96
97         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
98         public static Type GetType(String typeName, bool throwOnError) {
99             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
100             return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark);
101         }
102
103         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
104         public static Type GetType(String typeName) {
105             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
106
107             return RuntimeType.GetType(typeName, false, false, false, ref stackMark);
108         }
109 #endif
110 #if !FEATURE_CORECLR
111         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
112         public static Type GetType(
113             string typeName,
114             Func<AssemblyName, Assembly> assemblyResolver,
115             Func<Assembly, string, bool, Type> typeResolver)
116         {
117             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
118             return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark);
119         }
120
121         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
122         public static Type GetType(
123             string typeName,
124             Func<AssemblyName, Assembly> assemblyResolver,
125             Func<Assembly, string, bool, Type> typeResolver,
126             bool throwOnError)
127         {
128             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
129             return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark);
130         }
131
132         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
133         public static Type GetType(
134             string typeName,
135             Func<AssemblyName, Assembly> assemblyResolver,
136             Func<Assembly, string, bool, Type> typeResolver,
137             bool throwOnError,
138             bool ignoreCase)
139         {
140             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
141             return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
142         }
143 #endif //!FEATURE_CORECLR
144 #if !MONO
145         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
146         public static Type ReflectionOnlyGetType(String typeName, bool throwIfNotFound, bool ignoreCase) 
147         {
148             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
149             return RuntimeType.GetType(typeName, throwIfNotFound, ignoreCase, true /*reflectionOnly*/, ref stackMark);
150         }
151 #endif
152         public virtual Type MakePointerType() { throw new NotSupportedException(); }
153         public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
154         public virtual Type MakeByRefType() { throw new NotSupportedException(); }
155         public virtual Type MakeArrayType() { throw new NotSupportedException(); }
156         public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
157
158 #if FEATURE_COMINTEROP || MONO_COM || MOBILE_LEGACY
159         ////////////////////////////////////////////////////////////////////////////////
160         // This will return a class based upon the progID.  This is provided for 
161         // COM classic support.  Program ID's are not used in COM+ because they 
162         // have been superceded by namespace.  (This routine is called this instead 
163         // of getClass() because of the name conflict with the first method above.)
164         //
165         //   param progID:     the progID of the class to retrieve
166         //   returns:          the class object associated to the progID
167         ////
168         [System.Security.SecurityCritical]  // auto-generated_required
169         public static Type GetTypeFromProgID(String progID)
170         {
171                 return RuntimeType.GetTypeFromProgIDImpl(progID, null, false);
172         }
173
174         ////////////////////////////////////////////////////////////////////////////////
175         // This will return a class based upon the progID.  This is provided for 
176         // COM classic support.  Program ID's are not used in COM+ because they 
177         // have been superceded by namespace.  (This routine is called this instead 
178         // of getClass() because of the name conflict with the first method above.)
179         //
180         //   param progID:     the progID of the class to retrieve
181         //   returns:          the class object associated to the progID
182         ////
183         [System.Security.SecurityCritical]  // auto-generated_required
184         public static Type GetTypeFromProgID(String progID, bool throwOnError)
185         {
186                 return RuntimeType.GetTypeFromProgIDImpl(progID, null, throwOnError);
187         }
188
189         [System.Security.SecurityCritical]  // auto-generated_required
190         public static Type GetTypeFromProgID(String progID, String server)
191         {
192                 return RuntimeType.GetTypeFromProgIDImpl(progID, server, false);
193         }
194
195         [System.Security.SecurityCritical]  // auto-generated_required
196         public static Type GetTypeFromProgID(String progID, String server, bool throwOnError)
197         {
198                 return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
199         }
200
201         ////////////////////////////////////////////////////////////////////////////////
202         // This will return a class based upon the CLSID.  This is provided for 
203         // COM classic support.  
204         //
205         //   param CLSID:      the CLSID of the class to retrieve
206         //   returns:          the class object associated to the CLSID
207         ////
208         [System.Security.SecuritySafeCritical]  // auto-generated
209         public static Type GetTypeFromCLSID(Guid clsid)
210         {
211                 return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
212         }
213
214         [System.Security.SecuritySafeCritical]  // auto-generated
215         public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError)
216         {
217                 return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError);
218         }
219
220         [System.Security.SecuritySafeCritical]  // auto-generated
221         public static Type GetTypeFromCLSID(Guid clsid, String server)
222         {
223                 return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, false);
224         }
225
226         [System.Security.SecuritySafeCritical]  // auto-generated
227         public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError)
228         {
229                 return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
230         }
231 #endif // FEATURE_COMINTEROP
232
233         // GetTypeCode
234         // This method will return a TypeCode for the passed
235         //  type.
236         public static TypeCode GetTypeCode(Type type)
237         {
238             if (type == null)
239                 return TypeCode.Empty;
240             return type.GetTypeCodeImpl();
241         }
242
243         protected virtual TypeCode GetTypeCodeImpl()
244         {
245             // System.RuntimeType overrides GetTypeCodeInternal
246             // so we can assume that this is not a runtime type
247
248             // this is true for EnumBuilder but not the other System.Type subclasses in BCL
249             if (this != UnderlyingSystemType && UnderlyingSystemType != null)
250                 return Type.GetTypeCode(UnderlyingSystemType);
251             
252             return TypeCode.Object;
253         }
254
255         // Property representing the GUID associated with a class.
256         public abstract Guid GUID {
257             get;
258         }
259
260         // Return the Default binder used by the system.
261         static public Binder DefaultBinder {
262             get {
263                 // Allocate the default binder if it hasn't been allocated yet.
264                 if (defaultBinder == null)
265                     CreateBinder();
266                 return defaultBinder;
267             }
268         }
269
270         static private void CreateBinder() 
271         {
272             if (defaultBinder == null)
273             {
274                 DefaultBinder binder = new DefaultBinder();
275                 Interlocked.CompareExchange<Binder>(ref defaultBinder, binder, null);
276             }
277         }
278
279        // Description of the Binding Process.
280        // We must invoke a method that is accessable and for which the provided
281        // parameters have the most specific match.  A method may be called if
282        // 1. The number of parameters in the method declaration equals the number of 
283        //      arguments provided to the invocation
284        // 2. The type of each argument can be converted by the binder to the
285        //      type of the type of the parameter.
286        //      
287        // The binder will find all of the matching methods.  These method are found based
288        // upon the type of binding requested (MethodInvoke, Get/Set Properties).  The set
289        // of methods is filtered by the name, number of arguments and a set of search modifiers
290        // defined in the Binder.
291        // 
292        // After the method is selected, it will be invoked.  Accessability is checked
293        // at that point.  The search may be control which set of methods are searched based
294        // upon the accessibility attribute associated with the method.
295        // 
296        // The BindToMethod method is responsible for selecting the method to be invoked.
297        // For the default binder, the most specific method will be selected.
298        // 
299        // This will invoke a specific member...
300
301         abstract public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target,
302                                     Object[] args, ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters);
303
304         [DebuggerStepThroughAttribute]
305         [Diagnostics.DebuggerHidden]
306         public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture)
307         {
308             return InvokeMember(name,invokeAttr,binder,target,args,null,culture,null);
309         }
310
311         [DebuggerStepThroughAttribute]
312         [Diagnostics.DebuggerHidden]
313         public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args)
314         {
315             return InvokeMember(name,invokeAttr,binder,target,args,null,null,null);
316         }
317
318 #if MONO
319         // Workaround for JIT bug with bad VTable lookup
320         //
321         //      MemberInfo mi = typeof (System.DBNull);
322         //      System.Console.WriteLine (mi.Module);
323         //
324         public override abstract Module Module { get; }
325 #else
326         // Module Property associated with a class.
327         // _Type.Module
328         public new abstract Module Module { get; }
329 #endif
330         // Assembly Property associated with a class.
331         public abstract Assembly Assembly {
332             [Pure]
333             get;
334         }
335
336         // Assembly Property associated with a class.
337         // A class handle is a unique integer value associated with
338         // each class.  The handle is unique during the process life time.
339         public virtual RuntimeTypeHandle TypeHandle
340         {
341             [Pure]
342             get
343             {
344                 throw new NotSupportedException();
345             }
346         }
347
348         internal virtual RuntimeTypeHandle GetTypeHandleInternal() {
349             return TypeHandle;
350         }
351
352         public static RuntimeTypeHandle GetTypeHandle(Object o)
353         {
354             if (o == null)
355                 throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
356
357             // 
358
359             return new RuntimeTypeHandle((RuntimeType)o.GetType());
360         }
361 #if !MONO
362         // Given a class handle, this will return the class for that handle.
363         [System.Security.SecurityCritical]
364         [ResourceExposure(ResourceScope.None)]
365         [MethodImpl(MethodImplOptions.InternalCall)]
366         internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle);
367
368         [Pure]
369         [System.Security.SecuritySafeCritical]  // auto-generated
370         [ResourceExposure(ResourceScope.None)]
371         [MethodImpl(MethodImplOptions.InternalCall)]
372         public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle);
373 #endif
374
375         // Return the fully qualified name.  The name does contain the namespace.
376         public abstract String FullName {
377             [Pure]
378             get;
379         }
380
381         // Return the name space of the class.  
382         public abstract String Namespace {
383             [Pure]
384             get;
385         }
386
387
388         public abstract String AssemblyQualifiedName {
389             [Pure]
390             get;
391         }
392
393
394         [Pure]
395         public virtual int GetArrayRank() {
396             Contract.Ensures(Contract.Result<int>() >= 0);
397             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
398         }
399
400         // Returns the base class for a class.  If this is an interface or has
401         // no base class null is returned.  Object is the only Type that does not 
402         // have a base class.  
403         public abstract Type BaseType {
404             [Pure]
405             get;
406         }
407
408
409         // GetConstructor
410         // This method will search for the specified constructor.  For constructors,
411         //  unlike everything else, the default is to not look for static methods.  The
412         //  reason is that we don't typically expose the class initializer.
413         [System.Runtime.InteropServices.ComVisible(true)]
414         public ConstructorInfo GetConstructor(BindingFlags bindingAttr,
415                                               Binder binder,
416                                               CallingConventions callConvention, 
417                                               Type[] types,
418                                               ParameterModifier[] modifiers)
419         {               
420            // Must provide some types (Type[0] for nothing)
421             if (types == null)
422                 throw new ArgumentNullException("types");
423             Contract.EndContractBlock();
424             for (int i=0;i<types.Length;i++)
425                 if (types[i] == null)
426                     throw new ArgumentNullException("types");
427             return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
428         }
429
430         [System.Runtime.InteropServices.ComVisible(true)]
431         public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
432         {
433             if (types == null)
434                 throw new ArgumentNullException("types");
435             Contract.EndContractBlock();
436             for (int i=0;i<types.Length;i++)
437                 if (types[i] == null)
438                     throw new ArgumentNullException("types");
439             return GetConstructorImpl(bindingAttr, binder, CallingConventions.Any, types, modifiers);
440         }
441
442         [System.Runtime.InteropServices.ComVisible(true)]
443         public ConstructorInfo GetConstructor(Type[] types)
444         {
445             // The arguments are checked in the called version of GetConstructor.
446             return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
447         }
448
449         abstract protected ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,
450                                                               Binder binder,
451                                                               CallingConventions callConvention, 
452                                                               Type[] types,
453                                                               ParameterModifier[] modifiers);
454
455         // GetConstructors()
456         // This routine will return an array of all constructors supported by the class.
457         //  Unlike everything else, the default is to not look for static methods.  The
458         //  reason is that we don't typically expose the class initializer.
459         [System.Runtime.InteropServices.ComVisible(true)]
460         public ConstructorInfo[] GetConstructors() {
461             return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
462         }
463  
464         [System.Runtime.InteropServices.ComVisible(true)]
465         abstract public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
466
467         [System.Runtime.InteropServices.ComVisible(true)]
468         public ConstructorInfo TypeInitializer {
469             get {
470                 return GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
471                                           null,
472                                           CallingConventions.Any,
473                                           Type.EmptyTypes,
474                                           null);
475             }
476         }
477
478
479         // Return a method based upon the passed criteria.  The name of the method
480         // must be provided, and exception is thrown if it is not.  The bindingAttr
481         // parameter indicates if non-public methods should be searched.  The types
482         // array indicates the types of the parameters being looked for.
483         public MethodInfo GetMethod(String name,
484                                     BindingFlags bindingAttr,
485                                     Binder binder,
486                                     CallingConventions callConvention,
487                                     Type[] types,
488                                     ParameterModifier[] modifiers)
489         {
490             if (name == null)
491                 throw new ArgumentNullException("name");
492             if (types == null)
493                 throw new ArgumentNullException("types");
494             Contract.EndContractBlock();
495             for (int i = 0; i < types.Length; i++)
496                 if (types[i] == null)
497                     throw new ArgumentNullException("types");
498             return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
499         }
500
501         public MethodInfo GetMethod(String name,
502                                     BindingFlags bindingAttr,
503                                     Binder binder,
504                                     Type[] types,
505                                     ParameterModifier[] modifiers)
506         {
507             if (name == null)
508                 throw new ArgumentNullException("name");
509             if (types == null)
510                 throw new ArgumentNullException("types");
511             Contract.EndContractBlock();
512             for (int i = 0; i < types.Length; i++)
513                 if (types[i] == null)
514                     throw new ArgumentNullException("types");
515             return GetMethodImpl(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
516         }
517
518         public MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers)
519         {
520             if (name == null)
521                 throw new ArgumentNullException("name");
522             if (types == null)
523                 throw new ArgumentNullException("types");
524             Contract.EndContractBlock();
525             for (int i=0;i<types.Length;i++)
526                 if (types[i] == null)
527                     throw new ArgumentNullException("types");
528             return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, modifiers);
529         }
530
531         public MethodInfo GetMethod(String name,Type[] types)
532         {
533             if (name == null)
534                 throw new ArgumentNullException("name");
535             if (types == null)
536                 throw new ArgumentNullException("types");
537             Contract.EndContractBlock();
538             for (int i=0;i<types.Length;i++)
539                 if (types[i] == null)
540                     throw new ArgumentNullException("types");
541             return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, null);
542         }
543
544         public MethodInfo GetMethod(String name, BindingFlags bindingAttr)
545         {
546             if (name == null)
547                 throw new ArgumentNullException("name");
548             Contract.EndContractBlock();
549             return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
550         }
551
552         public MethodInfo GetMethod(String name)
553         {
554             if (name == null)
555                 throw new ArgumentNullException("name");
556             Contract.EndContractBlock();
557             return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null);
558         }
559
560         abstract protected MethodInfo GetMethodImpl(String name,
561                                                     BindingFlags bindingAttr,
562                                                     Binder binder,
563                                                     CallingConventions callConvention, 
564                                                     Type[] types,
565                                                     ParameterModifier[] modifiers);
566
567
568         // GetMethods
569         // This routine will return all the methods implemented by the class
570         public MethodInfo[] GetMethods() {
571             return GetMethods(Type.DefaultLookup);
572         }
573
574         abstract public MethodInfo[] GetMethods(BindingFlags bindingAttr);
575
576         // GetField
577         // Get Field will return a specific field based upon name
578         abstract public FieldInfo GetField(String name, BindingFlags bindingAttr);
579
580
581         public FieldInfo GetField(String name) {
582             return GetField(name, Type.DefaultLookup);
583         }
584
585
586         // GetFields
587         // Get fields will return a full array of fields implemented by a class
588         public FieldInfo[] GetFields() {
589             return GetFields(Type.DefaultLookup);
590         }
591         abstract public FieldInfo[] GetFields(BindingFlags bindingAttr);
592
593         // GetInterface
594         // This method will return an interface (as a class) based upon
595         //  the passed in name.
596         public Type GetInterface(String name) {
597             return GetInterface(name,false);
598         }
599         abstract public Type GetInterface(String name, bool ignoreCase);
600
601
602         // GetInterfaces
603         // This method will return all of the interfaces implemented by a class
604         abstract public Type[] GetInterfaces();
605
606         // FindInterfaces
607         // This method will filter the interfaces supported the class
608         public virtual Type[] FindInterfaces(TypeFilter filter,Object filterCriteria)
609         {
610             if (filter == null)
611                 throw new ArgumentNullException("filter");
612             Contract.EndContractBlock();
613             Type[] c = GetInterfaces();
614             int cnt = 0;
615             for (int i = 0;i<c.Length;i++) {
616                 if (!filter(c[i],filterCriteria))
617                     c[i] = null;
618                 else
619                     cnt++;
620             }
621             if (cnt == c.Length)
622                 return c;
623             
624             Type[] ret = new Type[cnt];
625             cnt=0;
626             for (int i=0;i<c.Length;i++) {
627                 if (c[i] != null)
628                     ret[cnt++] = c[i];
629             }
630             return ret;
631         }
632
633         // GetEvent
634         // This method will return a event by name if it is found.
635         //  null is returned if the event is not found
636
637
638         public EventInfo GetEvent(String name) {
639             return GetEvent(name,Type.DefaultLookup);
640         }
641         abstract public EventInfo GetEvent(String name,BindingFlags bindingAttr);
642
643         // GetEvents
644         // This method will return an array of EventInfo.  If there are not Events
645         //  an empty array will be returned.         
646         virtual public EventInfo[] GetEvents() {
647             return GetEvents(Type.DefaultLookup);
648         }
649         abstract public EventInfo[] GetEvents(BindingFlags bindingAttr);
650
651
652         // Return a property based upon the passed criteria.  The nameof the
653         // parameter must be provided.  
654         public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder, 
655                         Type returnType, Type[] types, ParameterModifier[] modifiers)
656         {
657             if (name == null)
658                 throw new ArgumentNullException("name");
659             if (types == null)
660                 throw new ArgumentNullException("types");
661             Contract.EndContractBlock();
662             return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
663         }
664
665         public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
666         {
667             if (name == null)
668                 throw new ArgumentNullException("name");
669             if (types == null)
670                 throw new ArgumentNullException("types");
671             Contract.EndContractBlock();
672             return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
673         }
674
675         public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
676         {
677             if (name == null)
678                 throw new ArgumentNullException("name");
679             Contract.EndContractBlock();
680             return GetPropertyImpl(name,bindingAttr,null,null,null,null);
681         }
682
683         public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
684         {
685             if (name == null)
686                 throw new ArgumentNullException("name");
687             if (types == null)
688                 throw new ArgumentNullException("types");
689             Contract.EndContractBlock();
690             return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
691         }
692
693         public PropertyInfo GetProperty(String name, Type[] types)
694         {
695             if (name == null)
696                 throw new ArgumentNullException("name");
697             if (types == null)
698                 throw new ArgumentNullException("types");
699             Contract.EndContractBlock();
700             return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
701         }
702
703         public PropertyInfo GetProperty(String name, Type returnType)
704         {
705             if (name == null)
706                 throw new ArgumentNullException("name");
707             if (returnType == null)
708                 throw new ArgumentNullException("returnType");
709             Contract.EndContractBlock();
710             return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
711         }
712
713         internal PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Type returnType)
714         {
715             if (name == null)
716                 throw new ArgumentNullException("name");
717             if (returnType == null)
718                 throw new ArgumentNullException("returnType");
719             Contract.EndContractBlock();
720             return GetPropertyImpl(name, bindingAttr, null, returnType, null, null);
721         }
722
723         public PropertyInfo GetProperty(String name)
724         {
725             if (name == null)
726                 throw new ArgumentNullException("name");
727             Contract.EndContractBlock();
728             return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
729         }
730
731         protected abstract PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr,Binder binder,
732                         Type returnType, Type[] types, ParameterModifier[] modifiers);
733
734
735         // GetProperties
736         // This method will return an array of all of the properties defined
737         //  for a Type.
738         abstract public PropertyInfo[] GetProperties(BindingFlags bindingAttr);
739         public PropertyInfo[] GetProperties()
740         {
741             return GetProperties(Type.DefaultLookup);
742         }
743 #if     !FEATURE_CORECLR
744 #endif  
745         // GetNestedTypes()
746         // This set of method will return any nested types that are found inside
747         //  of the type.
748         public Type[] GetNestedTypes()
749         {
750             return GetNestedTypes(Type.DefaultLookup);
751         }
752
753         abstract public Type[] GetNestedTypes(BindingFlags bindingAttr);
754
755 #if     !FEATURE_CORECLR
756         // GetNestedType()
757 #endif
758         public Type GetNestedType(String name)
759         {
760             return GetNestedType(name,Type.DefaultLookup);
761         }
762
763         abstract public Type GetNestedType(String name, BindingFlags bindingAttr);
764
765         // GetMember
766         // This method will return all of the members which match the specified string
767         // passed into the method
768         public MemberInfo[] GetMember(String name) {
769             return GetMember(name,Type.DefaultLookup);
770         }
771
772         virtual public MemberInfo[] GetMember(String name, BindingFlags bindingAttr)
773         {
774             return GetMember(name,MemberTypes.All,bindingAttr);
775         }
776          
777         virtual public MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
778         {
779             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
780         }
781
782
783         // GetMembers
784         // This will return a Member array of all of the members of a class
785         public MemberInfo[] GetMembers() {
786             return GetMembers(Type.DefaultLookup);
787         }
788         abstract public MemberInfo[] GetMembers(BindingFlags bindingAttr);
789
790         // GetDefaultMembers
791         // This will return a MemberInfo that has been marked with the
792         //      DefaultMemberAttribute
793         public virtual MemberInfo[] GetDefaultMembers()
794         {
795             throw new NotImplementedException();
796         }
797
798         // FindMembers
799         // This will return a filtered version of the member information
800         public virtual MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria)
801         {
802             // Define the work arrays
803             MethodInfo[] m = null;
804             ConstructorInfo[] c = null;
805             FieldInfo[] f = null;
806             PropertyInfo[] p = null;
807             EventInfo[] e = null;
808             Type[] t = null;
809             
810             int i = 0;
811             int cnt = 0;            // Total Matchs
812             
813             // Check the methods
814             if ((memberType & System.Reflection.MemberTypes.Method) != 0) {
815                 m = GetMethods(bindingAttr);
816                 if (filter != null) {
817                     for (i=0;i<m.Length;i++)
818                         if (!filter(m[i],filterCriteria))
819                             m[i] = null;
820                         else
821                             cnt++;
822                 } else {
823                     cnt+=m.Length;
824                 }
825             }
826             
827             // Check the constructors
828             if ((memberType & System.Reflection.MemberTypes.Constructor) != 0) {
829                 c = GetConstructors(bindingAttr);
830                 if (filter != null) {
831                     for (i=0;i<c.Length;i++)
832                         if (!filter(c[i],filterCriteria))
833                             c[i] = null;
834                         else
835                             cnt++;
836                 } else {
837                     cnt+=c.Length;
838                 }
839             }
840             
841             // Check the fields
842             if ((memberType & System.Reflection.MemberTypes.Field) != 0) {
843                 f = GetFields(bindingAttr);
844                 if (filter != null) {
845                     for (i=0;i<f.Length;i++)
846                         if (!filter(f[i],filterCriteria))
847                             f[i] = null;
848                         else
849                             cnt++;
850                 } else {
851                     cnt+=f.Length;
852                 }
853             }
854             
855             // Check the Properties
856             if ((memberType & System.Reflection.MemberTypes.Property) != 0) {
857                 p = GetProperties(bindingAttr);
858                 if (filter != null) {
859                     for (i=0;i<p.Length;i++)
860                         if (!filter(p[i],filterCriteria))
861                             p[i] = null;
862                         else
863                             cnt++;
864                 } else {
865                     cnt+=p.Length;
866                 }
867             }
868             
869             // Check the Events
870             if ((memberType & System.Reflection.MemberTypes.Event) != 0) {
871                 e = GetEvents(bindingAttr);
872                 if (filter != null) {
873                     for (i=0;i<e.Length;i++)
874                         if (!filter(e[i],filterCriteria))
875                             e[i] = null;
876                         else
877                             cnt++;
878                 } else {
879                     cnt+=e.Length;
880                 }
881             }
882             
883             // Check the Types
884             if ((memberType & System.Reflection.MemberTypes.NestedType) != 0) {
885                 t = GetNestedTypes(bindingAttr);
886                 if (filter != null) {
887                     for (i=0;i<t.Length;i++)
888                         if (!filter(t[i],filterCriteria))
889                             t[i] = null;
890                         else
891                             cnt++;
892                 } else {
893                     cnt+=t.Length;
894                 }
895             }
896             
897             // Allocate the Member Info
898             MemberInfo[] ret = new MemberInfo[cnt];
899             
900             // Copy the Methods
901             cnt = 0;
902             if (m != null) {
903                 for (i=0;i<m.Length;i++)
904                     if (m[i] != null)
905                         ret[cnt++] = m[i];
906             }
907             
908             // Copy the Constructors
909             if (c != null) {
910                 for (i=0;i<c.Length;i++)
911                     if (c[i] != null)
912                         ret[cnt++] = c[i];
913             }
914             
915             // Copy the Fields
916             if (f != null) {
917                 for (i=0;i<f.Length;i++)
918                     if (f[i] != null)
919                         ret[cnt++] = f[i];
920             }
921             
922             // Copy the Properties
923             if (p != null) {
924                 for (i=0;i<p.Length;i++)
925                     if (p[i] != null)
926                         ret[cnt++] = p[i];
927             }
928             
929             // Copy the Events
930             if (e != null) {
931                 for (i=0;i<e.Length;i++)
932                     if (e[i] != null)
933                         ret[cnt++] = e[i];
934             }
935             
936             // Copy the Types
937             if (t != null) {
938                 for (i=0;i<t.Length;i++)
939                     if (t[i] != null)
940                         ret[cnt++] = t[i];
941             }
942             
943             return ret;
944         }
945
946     ////////////////////////////////////////////////////////////////////////////////
947     //
948     // Attributes
949     //
950     //   The attributes are all treated as read-only properties on a class.  Most of
951     //  these boolean properties have flag values defined in this class and act like
952     //  a bit mask of attributes.  There are also a set of boolean properties that
953     //  relate to the classes relationship to other classes and to the state of the
954     //  class inside the runtime.
955     //
956     ////////////////////////////////////////////////////////////////////////////////
957
958         public bool IsNested 
959         {
960             [Pure]
961             get 
962             {
963                 return DeclaringType != null; 
964             }
965         }
966
967         // The attribute property on the Type.
968         public TypeAttributes Attributes     {
969             [Pure]
970             get {return GetAttributeFlagsImpl();}
971         }
972
973         public virtual GenericParameterAttributes GenericParameterAttributes
974         {
975             get { throw new NotSupportedException(); }
976         }
977
978         public bool IsVisible
979         {
980             [Pure]
981             get 
982             {
983 #if !MONO
984                 // .NET has unmanaged version of exactly same managed
985                 // code bellow
986                 RuntimeType rt = this as RuntimeType;
987                 if (rt != null)
988                     return RuntimeTypeHandle.IsVisible(rt);
989 #endif
990                 if (IsGenericParameter)
991                     return true;
992
993                 if (HasElementType)
994                     return GetElementType().IsVisible;
995
996                 Type type = this;
997                 while (type.IsNested)
998                 {
999                     if (!type.IsNestedPublic)
1000                         return false;
1001
1002                     // this should be null for non-nested types.
1003                     type = type.DeclaringType;
1004                 }
1005
1006                 // Now "type" should be a top level type
1007                 if (!type.IsPublic)
1008                     return false;
1009
1010                 if (IsGenericType && !IsGenericTypeDefinition)
1011                 {
1012                     foreach (Type t in GetGenericArguments())
1013                     {
1014                         if (!t.IsVisible)
1015                             return false;
1016                     }
1017                 }
1018
1019                 return true;
1020             }
1021         }
1022
1023         public bool IsNotPublic
1024         {
1025             [Pure]
1026             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic);}
1027         }
1028
1029         public bool IsPublic {
1030             [Pure]
1031             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public);}
1032         }
1033
1034         public bool IsNestedPublic {
1035             [Pure]
1036             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic);}
1037         }
1038
1039         public bool IsNestedPrivate {
1040             [Pure]
1041             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate);}
1042         }
1043         public bool IsNestedFamily {
1044             [Pure]
1045             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily);}
1046         }
1047         public bool IsNestedAssembly {
1048             [Pure]
1049             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly);}
1050         }
1051         public bool IsNestedFamANDAssem {
1052             [Pure]
1053             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem);}
1054         }
1055         public bool IsNestedFamORAssem{
1056             [Pure]
1057             get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem);}
1058         }
1059
1060         public bool IsAutoLayout {
1061             [Pure]
1062             get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout);}
1063         }
1064         public bool IsLayoutSequential {
1065             [Pure]
1066             get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout);}
1067         }
1068         public bool IsExplicitLayout {
1069             [Pure]
1070             get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout);}
1071         }
1072
1073         public bool IsClass {
1074             [Pure]
1075             get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType);}
1076         }
1077
1078         public bool IsInterface {
1079             [Pure]
1080             [System.Security.SecuritySafeCritical]  // auto-generated
1081             get
1082             {
1083                 RuntimeType rt = this as RuntimeType;
1084                 if (rt != null)
1085                     return RuntimeTypeHandle.IsInterface(rt);
1086
1087                 return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);
1088             }
1089         }
1090
1091         public bool IsValueType {
1092             [Pure]
1093             get {return IsValueTypeImpl();}
1094         }
1095
1096         public bool IsAbstract {
1097             [Pure]
1098              get { return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0); }
1099          }
1100          
1101         public bool IsSealed {
1102             [Pure]
1103             get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
1104         }       
1105         
1106 #if FEATURE_CORECLR
1107          public bool IsEnum {
1108 #else
1109          public virtual bool IsEnum {
1110 #endif
1111              [Pure]
1112              get
1113              {
1114                 // This will return false for a non-runtime Type object unless it overrides IsSubclassOf.
1115                 return IsSubclassOf(RuntimeType.EnumType);
1116              }
1117          }
1118         
1119          public bool IsSpecialName {
1120              [Pure]
1121             get {return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0);}
1122        }
1123
1124          public bool IsImport {
1125              [Pure]
1126             get {return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0);}
1127         }
1128
1129         public virtual bool IsSerializable
1130         {
1131             [Pure]
1132             get
1133             {
1134                 if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0)
1135                     return true;
1136
1137                 RuntimeType rt = this.UnderlyingSystemType as RuntimeType;
1138
1139                 if (rt != null)
1140                     return rt.IsSpecialSerializableType();
1141
1142                 return false;
1143             }
1144         }
1145
1146          public bool IsAnsiClass {
1147              [Pure]
1148             get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass);}
1149         }
1150
1151          public bool IsUnicodeClass {
1152              [Pure]
1153             get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass);}
1154         }
1155
1156          public bool IsAutoClass {
1157              [Pure]
1158             get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass);}
1159         }
1160                 
1161          // These are not backed up by attributes.  Instead they are implemented
1162          //      based internally.
1163          public bool IsArray {
1164              [Pure]
1165              get {return IsArrayImpl();}
1166          }
1167
1168          internal virtual bool IsSzArray {
1169              [Pure]
1170             get {return false;}
1171         }
1172
1173          public virtual bool IsGenericType {
1174              [Pure]
1175             get { return false; }
1176         }
1177
1178          public virtual bool IsGenericTypeDefinition {
1179              [Pure]
1180             get { return false; }
1181         }
1182
1183         public virtual bool IsConstructedGenericType
1184         {
1185             [Pure]
1186             get { throw new NotImplementedException(); }
1187         }
1188
1189         public virtual bool IsGenericParameter
1190         {
1191             [Pure]
1192             get { return false; }
1193         }
1194
1195          public virtual int GenericParameterPosition {
1196              [Pure]
1197             get {throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter")); }
1198         }
1199
1200         public virtual bool ContainsGenericParameters 
1201         {
1202             [Pure]
1203             get 
1204             {
1205                 if (HasElementType)
1206                     return GetRootElementType().ContainsGenericParameters;
1207
1208                 if (IsGenericParameter)
1209                     return true;
1210             
1211                 if (!IsGenericType)
1212                     return false;
1213
1214                 Type[] genericArguments = GetGenericArguments();
1215                 for (int i = 0; i < genericArguments.Length; i++)
1216                 {
1217                     if (genericArguments[i].ContainsGenericParameters)
1218                         return true;
1219                 }
1220
1221                 return false;
1222             }
1223         }
1224
1225         [Pure]
1226         public virtual Type[] GetGenericParameterConstraints()
1227         {
1228             if (!IsGenericParameter)
1229                 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
1230             Contract.EndContractBlock();
1231
1232             throw new InvalidOperationException();
1233         }
1234
1235          public bool IsByRef {
1236              [Pure]
1237             get {return IsByRefImpl();}
1238         }
1239          public bool IsPointer {
1240              [Pure]
1241             get {return IsPointerImpl();}
1242         }
1243          public bool IsPrimitive {
1244              [Pure]
1245             get {return IsPrimitiveImpl();}
1246         }
1247          public bool IsCOMObject {
1248              [Pure]
1249             get {return IsCOMObjectImpl();}
1250         }
1251
1252 #if FEATURE_COMINTEROP || MONO_COM
1253         internal bool IsWindowsRuntimeObject {
1254             [Pure]
1255             get { return IsWindowsRuntimeObjectImpl(); }
1256         }
1257
1258         internal bool IsExportedToWindowsRuntime {
1259             [Pure]
1260             get { return IsExportedToWindowsRuntimeImpl(); }
1261         }
1262 #endif // FEATURE_COMINTEROP
1263
1264          public bool HasElementType {
1265              [Pure]
1266              get {return HasElementTypeImpl();}
1267          }
1268
1269          public bool IsContextful {
1270              [Pure]
1271             get {return IsContextfulImpl();}
1272         }
1273
1274          public bool IsMarshalByRef {
1275              [Pure]
1276              get {return IsMarshalByRefImpl();}
1277          }
1278
1279          internal bool HasProxyAttribute {
1280              [Pure]
1281             get {return HasProxyAttributeImpl();}
1282         }
1283                        
1284         // Protected routine to determine if this class represents a value class
1285         // The default implementation of IsValueTypeImpl never returns true for non-runtime types.
1286         protected virtual bool IsValueTypeImpl()
1287         {
1288             // Note that typeof(Enum) and typeof(ValueType) are not themselves value types.
1289             // But there is no point excluding them here because customer derived System.Type 
1290             // (non-runtime type) objects can never be equal to a runtime type, which typeof(XXX) is.
1291             // Ideally we should throw a NotImplementedException here or just return false because
1292             // customer implementations of IsSubclassOf should never return true between a non-runtime
1293             // type and a runtime type. There is no benefits in making that breaking change though.
1294
1295             return IsSubclassOf(RuntimeType.ValueType);
1296         }
1297
1298         // Protected routine to get the attributes.
1299         abstract protected TypeAttributes GetAttributeFlagsImpl();
1300             
1301         // Protected routine to determine if this class represents an Array
1302         abstract protected bool IsArrayImpl();
1303
1304         // Protected routine to determine if this class is a ByRef
1305         abstract protected bool IsByRefImpl();
1306
1307         // Protected routine to determine if this class is a Pointer
1308         abstract protected bool IsPointerImpl();
1309             
1310         // Protected routine to determine if this class represents a primitive type
1311         abstract protected bool IsPrimitiveImpl();
1312             
1313         // Protected routine to determine if this class represents a COM object
1314         abstract protected bool IsCOMObjectImpl();
1315
1316 #if FEATURE_COMINTEROP || MONO_COM
1317         // Protected routine to determine if this class represents a Windows Runtime object
1318         virtual internal bool IsWindowsRuntimeObjectImpl() {
1319             throw new NotImplementedException();
1320         }
1321
1322         // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd)
1323         virtual internal bool IsExportedToWindowsRuntimeImpl() {
1324             throw new NotImplementedException();
1325         }
1326 #endif // FEATURE_COMINTEROP
1327
1328         // 
1329         public virtual Type MakeGenericType(params Type[] typeArguments) {
1330             Contract.Ensures(Contract.Result<Type>() != null);
1331             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
1332         }
1333
1334     
1335         // Protected routine to determine if this class is contextful
1336         protected virtual bool IsContextfulImpl(){
1337             return typeof(ContextBoundObject).IsAssignableFrom(this);
1338         }
1339     
1340
1341         // Protected routine to determine if this class is marshaled by ref
1342         protected virtual bool IsMarshalByRefImpl(){
1343             return typeof(MarshalByRefObject).IsAssignableFrom(this);
1344         }
1345
1346         internal virtual bool HasProxyAttributeImpl()
1347         {
1348             // We will override this in RuntimeType
1349             return false;
1350         }
1351
1352         [Pure]
1353         abstract public Type GetElementType();
1354
1355         [Pure]
1356         public virtual Type[] GetGenericArguments() 
1357         { 
1358             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
1359         }
1360
1361         public virtual Type[] GenericTypeArguments{
1362             get{
1363                 if(IsGenericType && !IsGenericTypeDefinition){
1364                     return GetGenericArguments();
1365                 }
1366                 else{
1367                     return Type.EmptyTypes;
1368                 }
1369
1370             }
1371         }
1372
1373         [Pure]
1374         public virtual Type GetGenericTypeDefinition() 
1375         {
1376             Contract.Ensures(Contract.Result<Type>() != null);
1377             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
1378         }
1379
1380         [Pure]
1381         abstract protected bool HasElementTypeImpl();
1382
1383         internal Type GetRootElementType()
1384         {
1385             Type rootElementType = this;
1386
1387             while (rootElementType.HasElementType)
1388                 rootElementType = rootElementType.GetElementType();
1389
1390             return rootElementType;
1391         }
1392
1393         #region Enum methods
1394
1395         // Default implementations of GetEnumNames, GetEnumValues, and GetEnumUnderlyingType
1396         // Subclass of types can override these methods.
1397
1398         public virtual string[] GetEnumNames()
1399         {
1400             if (!IsEnum)
1401                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
1402             Contract.Ensures(Contract.Result<String[]>() != null);
1403
1404             string[] names;
1405             Array values;
1406             GetEnumData(out names, out values);
1407             return names;
1408         }
1409
1410         // We don't support GetEnumValues in the default implementation because we cannot create an array of
1411         // a non-runtime type. If there is strong need we can consider returning an object or int64 array.
1412         public virtual Array GetEnumValues()
1413         {
1414             if (!IsEnum)
1415                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
1416             Contract.Ensures(Contract.Result<Array>() != null);
1417
1418             throw new NotImplementedException();
1419         }
1420
1421         // Returns the enum values as an object array.
1422         private Array GetEnumRawConstantValues()
1423         {
1424             string[] names;
1425             Array values;
1426             GetEnumData(out names, out values);
1427             return values;
1428         }
1429
1430         // This will return enumValues and enumNames sorted by the values.
1431         private void GetEnumData(out string[] enumNames, out Array enumValues)
1432         {
1433             Contract.Ensures(Contract.ValueAtReturn<String[]>(out enumNames) != null);
1434             Contract.Ensures(Contract.ValueAtReturn<Array>(out enumValues) != null);
1435
1436             FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
1437
1438             object[] values = new object[flds.Length];
1439             string[] names = new string[flds.Length];
1440
1441             for (int i = 0; i < flds.Length; i++)
1442             {
1443                 names[i] = flds[i].Name;
1444                 values[i] = flds[i].GetRawConstantValue();
1445             }
1446
1447             // Insertion Sort these values in ascending order.
1448             // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
1449             // the common case performance will be faster than quick sorting this.
1450             IComparer comparer = Comparer.Default;
1451             for (int i = 1; i < values.Length; i++)
1452             {
1453                 int j = i;
1454                 string tempStr = names[i];
1455                 object val = values[i];
1456                 bool exchanged = false;
1457
1458                 // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
1459                 while (comparer.Compare(values[j - 1], val) > 0)
1460                 {
1461                     names[j] = names[j - 1];
1462                     values[j] = values[j - 1];
1463                     j--;
1464                     exchanged = true;
1465                     if (j == 0)
1466                         break;
1467                 }
1468
1469                 if (exchanged)
1470                 {
1471                     names[j] = tempStr;
1472                     values[j] = val;
1473                 }
1474             }
1475
1476             enumNames = names;
1477             enumValues = values;
1478         }
1479
1480         public virtual Type GetEnumUnderlyingType()
1481         {
1482             if (!IsEnum)
1483                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
1484             Contract.Ensures(Contract.Result<Type>() != null);
1485
1486             FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
1487             if (fields == null || fields.Length != 1)
1488                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnum"), "enumType");
1489
1490             return fields[0].FieldType;
1491         }
1492
1493         public virtual bool IsEnumDefined(object value)
1494         {
1495             if (value == null)
1496                 throw new ArgumentNullException("value");
1497
1498             if (!IsEnum)
1499                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
1500             Contract.EndContractBlock();
1501
1502             // Check if both of them are of the same type
1503             Type valueType = value.GetType();
1504
1505             // If the value is an Enum then we need to extract the underlying value from it
1506             if (valueType.IsEnum)
1507             {
1508                 if (!valueType.IsEquivalentTo(this))
1509                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
1510
1511                 valueType = valueType.GetEnumUnderlyingType();
1512             }
1513
1514             // If a string is passed in
1515             if (valueType == typeof(string))
1516             {
1517                 string[] names = GetEnumNames();
1518                 if (Array.IndexOf(names, value) >= 0)
1519                     return true;
1520                 else
1521                     return false;
1522             }
1523
1524             // If an enum or integer value is passed in
1525             if (Type.IsIntegerType(valueType))
1526             {
1527                 Type underlyingType = GetEnumUnderlyingType();
1528                 // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
1529                 if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
1530                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
1531
1532                 Array values = GetEnumRawConstantValues();
1533                 return (BinarySearch(values, value) >= 0);
1534             }
1535             else if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
1536             {
1537                 // if at this point the value type is not an integer type, then its type doesn't match the enum type
1538                 // NetCF used to throw an argument exception in this case
1539                 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), GetEnumUnderlyingType()));
1540             }
1541             else
1542             {
1543                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
1544             }
1545         }
1546
1547         public virtual string GetEnumName(object value)
1548         {
1549             if (value == null)
1550                 throw new ArgumentNullException("value");
1551
1552             if (!IsEnum)
1553                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
1554             Contract.EndContractBlock();
1555
1556             Type valueType = value.GetType();
1557
1558             if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
1559                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
1560
1561             Array values = GetEnumRawConstantValues();
1562             int index = BinarySearch(values, value);
1563
1564             if (index >= 0)
1565             {
1566                 string[] names = GetEnumNames();
1567                 return names[index];
1568             }
1569
1570             return null;
1571         }
1572
1573         // Convert everything to ulong then perform a binary search.
1574         private static int BinarySearch(Array array, object value)
1575         {
1576             ulong[] ulArray = new ulong[array.Length];
1577             for (int i = 0; i < array.Length; ++i)
1578                 ulArray[i] = Enum.ToUInt64(array.GetValue(i));
1579
1580             ulong ulValue = Enum.ToUInt64(value);
1581
1582             return Array.BinarySearch(ulArray, ulValue);
1583         }
1584
1585         internal static bool IsIntegerType(Type t)
1586         {
1587             return (t == typeof(int) ||
1588                     t == typeof(short) ||
1589                     t == typeof(ushort) ||
1590                     t == typeof(byte) ||
1591                     t == typeof(sbyte) ||
1592                     t == typeof(uint) ||
1593                     t == typeof(long) ||
1594                     t == typeof(ulong) ||
1595                     t == typeof(char) ||
1596                     t == typeof(bool));
1597         }
1598         #endregion
1599
1600         public virtual bool IsSecurityCritical { [Pure] get { throw new NotImplementedException(); } }
1601
1602         public virtual bool IsSecuritySafeCritical { [Pure] get { throw new NotImplementedException(); } }
1603
1604         public virtual bool IsSecurityTransparent { [Pure] get { throw new NotImplementedException(); } }
1605
1606         internal bool NeedsReflectionSecurityCheck
1607         {
1608             get
1609             {
1610                 if (!IsVisible)
1611                 {
1612                     // Types which are not externally visible require security checks
1613                     return true;
1614                 }
1615                 else if (IsSecurityCritical && !IsSecuritySafeCritical)
1616                 {
1617                     // Critical types require security checks
1618                     return true;
1619                 }
1620                 else if (IsGenericType)
1621                 {
1622                     // If any of the generic arguments to this type require a security check, then this type
1623                     // also requires one.
1624                     foreach (Type genericArgument in GetGenericArguments())
1625                     {
1626                         if (genericArgument.NeedsReflectionSecurityCheck)
1627                         {
1628                             return true;
1629                         }
1630                     }
1631                 }
1632                 else if (IsArray || IsPointer)
1633                 {
1634                     return GetElementType().NeedsReflectionSecurityCheck;
1635                 }
1636
1637                 return false;
1638             }
1639         }
1640
1641         // The behavior of UnderlyingSystemType varies from type to type.
1642         // For IReflect objects: Return the underlying Type that represents the IReflect Object.
1643         // For expando object: this is the (Object) IReflectInstance.GetType().  For Type object it is this.
1644         // It could also return the baked type or the underlying enum type in RefEmit. See the comment in
1645         // code:TypeBuilder.SetConstantValue.
1646         public abstract Type UnderlyingSystemType {
1647             get;
1648         }       
1649
1650         // Returns true of this class is a true subclass of c.  Everything 
1651         // else returns false.  If this class and c are the same class false is
1652         // returned.
1653         // 
1654         [System.Runtime.InteropServices.ComVisible(true)]
1655         [Pure]
1656         public virtual bool IsSubclassOf(Type c)
1657         {
1658             Type p = this;
1659             if (p == c)
1660                 return false;
1661             while (p != null) {
1662                 if (p == c)
1663                     return true;
1664                 p = p.BaseType;
1665             }
1666             return false;
1667         }
1668         
1669         // Returns true if the object passed is assignable to an instance of this class.
1670         // Everything else returns false. 
1671         // 
1672         [Pure]
1673         public virtual bool IsInstanceOfType(Object o) 
1674         {
1675             if (o == null)
1676                 return false;
1677
1678             // No need for transparent proxy casting check here
1679             // because it never returns true for a non-rutnime type.
1680             
1681             return IsAssignableFrom(o.GetType());
1682         }
1683         
1684         // Returns true if an instance of Type c may be assigned
1685         // to an instance of this class.  Return false otherwise.
1686         // 
1687         [Pure]
1688         public virtual bool IsAssignableFrom(Type c)
1689         {
1690             if (c == null)
1691                 return false;
1692
1693             if (this == c)
1694                 return true;
1695
1696             // For backward-compatibility, we need to special case for the types
1697             // whose UnderlyingSystemType are RuntimeType objects. 
1698             RuntimeType toType = this.UnderlyingSystemType as RuntimeType;
1699             if (toType != null)
1700                 return toType.IsAssignableFrom(c);
1701
1702             // If c is a subclass of this class, then c can be cast to this type.
1703             if (c.IsSubclassOf(this))
1704                 return true;
1705
1706             if (this.IsInterface)
1707             {
1708                 return c.ImplementInterface(this);
1709             }
1710             else if (IsGenericParameter)
1711             {
1712                 Type[] constraints = GetGenericParameterConstraints();
1713                 for (int i = 0; i < constraints.Length; i++)
1714                     if (!constraints[i].IsAssignableFrom(c))
1715                         return false;
1716
1717                 return true;
1718             }
1719
1720             return false;
1721         }
1722
1723         // Base implementation that does only ==.
1724         [Pure]
1725         public virtual bool IsEquivalentTo(Type other)
1726         {
1727             return (this == other);
1728         }
1729
1730         internal bool ImplementInterface(Type ifaceType)
1731         {
1732             Contract.Requires(ifaceType != null);
1733             Contract.Requires(ifaceType.IsInterface, "ifaceType must be an interface type");
1734
1735             Type t = this;
1736             while (t != null)
1737             {
1738                 Type[] interfaces = t.GetInterfaces();
1739                 if (interfaces != null)
1740                 {
1741                     for (int i = 0; i < interfaces.Length; i++)
1742                     {
1743                         // Interfaces don't derive from other interfaces, they implement them.
1744                         // So instead of IsSubclassOf, we should use ImplementInterface instead.
1745                         if (interfaces[i] == ifaceType || 
1746                             (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType)))
1747                             return true;
1748                     }
1749                 }
1750
1751                 t = t.BaseType;
1752             }
1753
1754             return false;
1755         }
1756
1757         // This is only ever called on RuntimeType objects.
1758         internal string FormatTypeName()
1759         {
1760             return FormatTypeName(false);
1761         }
1762
1763         internal virtual string FormatTypeName(bool serialization)
1764         {
1765             throw new NotImplementedException();
1766         }
1767
1768         // ToString
1769         // Print the String Representation of the Type
1770         public override String ToString()
1771         {
1772             // Why do we add the "Type: " prefix? RuntimeType.ToString() doesn't include it.
1773             return "Type: " + Name;
1774         }
1775
1776         // This method will return an array of classes based upon the array of 
1777         // types.
1778         public static Type[] GetTypeArray(Object[] args) {
1779             if (args == null)
1780                 throw new ArgumentNullException("args");
1781             Contract.EndContractBlock();
1782             Type[] cls = new Type[args.Length];
1783             for (int i = 0;i < cls.Length;i++)
1784             {
1785                 if (args[i] == null)
1786                     throw new ArgumentNullException();
1787                 cls[i] = args[i].GetType();
1788             }
1789             return cls;
1790         }
1791
1792         [Pure]
1793         public override bool Equals(Object o)
1794         {
1795             if (o == null)
1796                 return false;
1797
1798             return Equals(o as Type);
1799         }
1800
1801         // _Type.Equals(Type)
1802         [Pure]
1803 #if !FEATURE_CORECLR
1804         public virtual bool Equals(Type o)
1805 #else
1806         public bool Equals(Type o)
1807 #endif
1808         {
1809             if ((object)o == null)
1810                 return false;
1811
1812             return (Object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType));
1813         }
1814
1815 #if MONO
1816         public static bool operator == (Type left, Type right)
1817         {
1818             return object.ReferenceEquals (left, right);
1819         }
1820
1821         public static bool operator != (Type left, Type right)
1822         {
1823             return !object.ReferenceEquals (left, right);
1824         }
1825 #else
1826 #if !FEATURE_CORECLR
1827         [System.Security.SecuritySafeCritical]
1828         [Pure]
1829         [ResourceExposure(ResourceScope.None)]
1830         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1831         public static extern bool operator ==(Type left, Type right);
1832
1833         [System.Security.SecuritySafeCritical]
1834         [Pure]
1835         [ResourceExposure(ResourceScope.None)]
1836         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1837         public static extern bool operator !=(Type left, Type right);
1838 #endif // !FEATURE_CORECLR
1839 #endif
1840
1841         public override int GetHashCode()
1842         {
1843             Type SystemType = UnderlyingSystemType;
1844             if (!Object.ReferenceEquals(SystemType, this))
1845                 return SystemType.GetHashCode();
1846             return base.GetHashCode();
1847         }
1848
1849
1850         // GetInterfaceMap
1851         // This method will return an interface mapping for the interface
1852         //  requested.  It will throw an argument exception if the Type doesn't
1853         //  implemenet the interface.
1854         [System.Runtime.InteropServices.ComVisible(true)]
1855         public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
1856         {
1857             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
1858         }
1859
1860 #if !FEATURE_CORECLR
1861         // this method is required so Object.GetType is not made virtual by the compiler 
1862         // _Type.GetType()
1863         public new Type GetType()
1864         {
1865             return base.GetType();
1866         }
1867
1868         void _Type.GetTypeInfoCount(out uint pcTInfo)
1869         {
1870             throw new NotImplementedException();
1871         }
1872
1873         void _Type.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
1874         {
1875             throw new NotImplementedException();
1876         }
1877
1878         void _Type.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1879         {
1880             throw new NotImplementedException();
1881         }
1882
1883         // If you implement this method, make sure to include _Type.Invoke in VM\DangerousAPIs.h and 
1884         // include _Type in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
1885         void _Type.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1886         {
1887             throw new NotImplementedException();
1888         }
1889 #endif
1890
1891         // private convenience data
1892         private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
1893         internal const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
1894 }
1895
1896 #if CONTRACTS_FULL
1897     [ContractClassFor(typeof(Type))]
1898     internal abstract class TypeContracts : Type
1899     {
1900         public override FieldInfo[] GetFields(BindingFlags bindingAttr)
1901         {
1902             Contract.Ensures(Contract.Result<FieldInfo[]>() != null);
1903             return default(FieldInfo[]);
1904         }
1905
1906         public new static Type GetTypeFromHandle(RuntimeTypeHandle handle)
1907         {
1908             Contract.Ensures(Contract.Result<Type>() != null);
1909             return default(Type);
1910         }
1911
1912         public override Type[] GetInterfaces()
1913         {
1914             Contract.Ensures(Contract.Result<Type[]>() != null);
1915             return default(Type[]);
1916         }
1917     }
1918 #endif 
1919 }