summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Type.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Type.cs')
-rw-r--r--src/mscorlib/src/System/Type.cs1845
1 files changed, 1845 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Type.cs b/src/mscorlib/src/System/Type.cs
new file mode 100644
index 0000000000..730003307a
--- /dev/null
+++ b/src/mscorlib/src/System/Type.cs
@@ -0,0 +1,1845 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+//
+//
+//
+// Implements System.Type
+//
+// ======================================================================================
+
+namespace System {
+
+ using System;
+ using System.Reflection;
+ using System.Threading;
+ using System.Runtime;
+ using System.Runtime.Remoting;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Runtime.Versioning;
+ using System.Diagnostics.Contracts;
+ using CultureInfo = System.Globalization.CultureInfo;
+ using StackCrawlMark = System.Threading.StackCrawlMark;
+ using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
+
+ [Serializable]
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComDefaultInterface(typeof(_Type))]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public abstract class Type : MemberInfo, _Type, IReflect
+ {
+ //
+ // System.Type is appdomain agile type. Appdomain agile types cannot have precise static constructors. Make
+ // sure to never introduce one here!
+ //
+ public static readonly MemberFilter FilterAttribute = new MemberFilter(__Filters.Instance.FilterAttribute);
+ public static readonly MemberFilter FilterName = new MemberFilter(__Filters.Instance.FilterName);
+ public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter(__Filters.Instance.FilterIgnoreCase);
+
+ public static readonly Object Missing = System.Reflection.Missing.Value;
+
+ public static readonly char Delimiter = '.';
+
+ // EmptyTypes is used to indicate that we are looking for someting without any parameters.
+ public readonly static Type[] EmptyTypes = EmptyArray<Type>.Value;
+
+ // The Default binder. We create a single one and expose that.
+ private static Binder defaultBinder;
+
+
+ protected Type() {}
+
+
+ // MemberInfo Methods....
+ // The Member type Field.
+ public override MemberTypes MemberType {
+ get {return System.Reflection.MemberTypes.TypeInfo;}
+ }
+
+ // Return the class that declared this type.
+ public override Type DeclaringType {
+ get {return null;}
+ }
+
+ public virtual MethodBase DeclaringMethod { get { return null; } }
+
+ // Return the class that was used to obtain this type.
+ public override Type ReflectedType
+ {
+ get {return null;}
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This is a static method that returns a Class based upon the name of the class
+ // (this name needs to be fully qualified with the package name and is
+ // case-sensitive by default).
+ ////
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(String typeName, bool throwOnError) {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(String typeName) {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, false, false, false, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver,
+ bool throwOnError)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver,
+ bool throwOnError,
+ bool ignoreCase)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Type ReflectionOnlyGetType(String typeName, bool throwIfNotFound, bool ignoreCase)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, throwIfNotFound, ignoreCase, true /*reflectionOnly*/, ref stackMark);
+ }
+
+ public virtual Type MakePointerType() { throw new NotSupportedException(); }
+ public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
+ public virtual Type MakeByRefType() { throw new NotSupportedException(); }
+ public virtual Type MakeArrayType() { throw new NotSupportedException(); }
+ public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This will return a class based upon the progID. This is provided for
+ // COM classic support. Program ID's are not used in COM+ because they
+ // have been superceded by namespace. (This routine is called this instead
+ // of getClass() because of the name conflict with the first method above.)
+ //
+ // param progID: the progID of the class to retrieve
+ // returns: the class object associated to the progID
+ ////
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeFromProgID(String progID)
+ {
+ return RuntimeType.GetTypeFromProgIDImpl(progID, null, false);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This will return a class based upon the progID. This is provided for
+ // COM classic support. Program ID's are not used in COM+ because they
+ // have been superceded by namespace. (This routine is called this instead
+ // of getClass() because of the name conflict with the first method above.)
+ //
+ // param progID: the progID of the class to retrieve
+ // returns: the class object associated to the progID
+ ////
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeFromProgID(String progID, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromProgIDImpl(progID, null, throwOnError);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeFromProgID(String progID, String server)
+ {
+ return RuntimeType.GetTypeFromProgIDImpl(progID, server, false);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeFromProgID(String progID, String server, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This will return a class based upon the CLSID. This is provided for
+ // COM classic support.
+ //
+ // param CLSID: the CLSID of the class to retrieve
+ // returns: the class object associated to the CLSID
+ ////
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static Type GetTypeFromCLSID(Guid clsid)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static Type GetTypeFromCLSID(Guid clsid, String server)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, false);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
+ }
+
+ // GetTypeCode
+ // This method will return a TypeCode for the passed
+ // type.
+ public static TypeCode GetTypeCode(Type type)
+ {
+ if (type == null)
+ return TypeCode.Empty;
+ return type.GetTypeCodeImpl();
+ }
+
+ protected virtual TypeCode GetTypeCodeImpl()
+ {
+ // System.RuntimeType overrides GetTypeCodeInternal
+ // so we can assume that this is not a runtime type
+
+ // this is true for EnumBuilder but not the other System.Type subclasses in BCL
+ if (this != UnderlyingSystemType && UnderlyingSystemType != null)
+ return Type.GetTypeCode(UnderlyingSystemType);
+
+ return TypeCode.Object;
+ }
+
+ // Property representing the GUID associated with a class.
+ public abstract Guid GUID {
+ get;
+ }
+
+ // Return the Default binder used by the system.
+ static public Binder DefaultBinder {
+ get {
+ // Allocate the default binder if it hasn't been allocated yet.
+ if (defaultBinder == null)
+ CreateBinder();
+ return defaultBinder;
+ }
+ }
+
+ static private void CreateBinder()
+ {
+ if (defaultBinder == null)
+ {
+ DefaultBinder binder = new DefaultBinder();
+ Interlocked.CompareExchange<Binder>(ref defaultBinder, binder, null);
+ }
+ }
+
+ // Description of the Binding Process.
+ // We must invoke a method that is accessable and for which the provided
+ // parameters have the most specific match. A method may be called if
+ // 1. The number of parameters in the method declaration equals the number of
+ // arguments provided to the invocation
+ // 2. The type of each argument can be converted by the binder to the
+ // type of the type of the parameter.
+ //
+ // The binder will find all of the matching methods. These method are found based
+ // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set
+ // of methods is filtered by the name, number of arguments and a set of search modifiers
+ // defined in the Binder.
+ //
+ // After the method is selected, it will be invoked. Accessability is checked
+ // at that point. The search may be control which set of methods are searched based
+ // upon the accessibility attribute associated with the method.
+ //
+ // The BindToMethod method is responsible for selecting the method to be invoked.
+ // For the default binder, the most specific method will be selected.
+ //
+ // This will invoke a specific member...
+
+ abstract public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target,
+ Object[] args, ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters);
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture)
+ {
+ return InvokeMember(name,invokeAttr,binder,target,args,null,culture,null);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args)
+ {
+ return InvokeMember(name,invokeAttr,binder,target,args,null,null,null);
+ }
+
+
+ // Module Property associated with a class.
+ // _Type.Module
+ public new abstract Module Module { get; }
+
+ // Assembly Property associated with a class.
+ public abstract Assembly Assembly {
+ [Pure]
+ get;
+ }
+
+ // Assembly Property associated with a class.
+ // A class handle is a unique integer value associated with
+ // each class. The handle is unique during the process life time.
+ public virtual RuntimeTypeHandle TypeHandle
+ {
+ [Pure]
+ get
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ internal virtual RuntimeTypeHandle GetTypeHandleInternal() {
+ return TypeHandle;
+ }
+
+ public static RuntimeTypeHandle GetTypeHandle(Object o)
+ {
+ if (o == null)
+ throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
+ return new RuntimeTypeHandle((RuntimeType)o.GetType());
+ }
+
+ // Given a class handle, this will return the class for that handle.
+ [System.Security.SecurityCritical]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle);
+
+ [Pure]
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle);
+
+
+ // Return the fully qualified name. The name does contain the namespace.
+ public abstract String FullName {
+ [Pure]
+ get;
+ }
+
+ // Return the name space of the class.
+ public abstract String Namespace {
+ [Pure]
+ get;
+ }
+
+
+ public abstract String AssemblyQualifiedName {
+ [Pure]
+ get;
+ }
+
+
+ [Pure]
+ public virtual int GetArrayRank() {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+ // Returns the base class for a class. If this is an interface or has
+ // no base class null is returned. Object is the only Type that does not
+ // have a base class.
+ public abstract Type BaseType {
+ [Pure]
+ get;
+ }
+
+
+ // GetConstructor
+ // This method will search for the specified constructor. For constructors,
+ // unlike everything else, the default is to not look for static methods. The
+ // reason is that we don't typically expose the class initializer.
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public ConstructorInfo GetConstructor(BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers)
+ {
+ // Must provide some types (Type[0] for nothing)
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i=0;i<types.Length;i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i=0;i<types.Length;i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetConstructorImpl(bindingAttr, binder, CallingConventions.Any, types, modifiers);
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public ConstructorInfo GetConstructor(Type[] types)
+ {
+ // The arguments are checked in the called version of GetConstructor.
+ return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
+ }
+
+ abstract protected ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers);
+
+ // GetConstructors()
+ // This routine will return an array of all constructors supported by the class.
+ // Unlike everything else, the default is to not look for static methods. The
+ // reason is that we don't typically expose the class initializer.
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public ConstructorInfo[] GetConstructors() {
+ return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ abstract public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public ConstructorInfo TypeInitializer {
+ get {
+ return GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
+ null,
+ CallingConventions.Any,
+ Type.EmptyTypes,
+ null);
+ }
+ }
+
+
+ // Return a method based upon the passed criteria. The name of the method
+ // must be provided, and exception is thrown if it is not. The bindingAttr
+ // parameter indicates if non-public methods should be searched. The types
+ // array indicates the types of the parameters being looked for.
+ public MethodInfo GetMethod(String name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i = 0; i < types.Length; i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ public MethodInfo GetMethod(String name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ Type[] types,
+ ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i = 0; i < types.Length; i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetMethodImpl(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
+ }
+
+ public MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i=0;i<types.Length;i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, modifiers);
+ }
+
+ public MethodInfo GetMethod(String name,Type[] types)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ for (int i=0;i<types.Length;i++)
+ if (types[i] == null)
+ throw new ArgumentNullException("types");
+ return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, null);
+ }
+
+ public MethodInfo GetMethod(String name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ Contract.EndContractBlock();
+ return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
+ }
+
+ public MethodInfo GetMethod(String name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ Contract.EndContractBlock();
+ return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null);
+ }
+
+ abstract protected MethodInfo GetMethodImpl(String name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types,
+ ParameterModifier[] modifiers);
+
+
+ // GetMethods
+ // This routine will return all the methods implemented by the class
+ public MethodInfo[] GetMethods() {
+ return GetMethods(Type.DefaultLookup);
+ }
+
+ abstract public MethodInfo[] GetMethods(BindingFlags bindingAttr);
+
+ // GetField
+ // Get Field will return a specific field based upon name
+ abstract public FieldInfo GetField(String name, BindingFlags bindingAttr);
+
+
+ public FieldInfo GetField(String name) {
+ return GetField(name, Type.DefaultLookup);
+ }
+
+
+ // GetFields
+ // Get fields will return a full array of fields implemented by a class
+ public FieldInfo[] GetFields() {
+ return GetFields(Type.DefaultLookup);
+ }
+ abstract public FieldInfo[] GetFields(BindingFlags bindingAttr);
+
+ // GetInterface
+ // This method will return an interface (as a class) based upon
+ // the passed in name.
+ public Type GetInterface(String name) {
+ return GetInterface(name,false);
+ }
+ abstract public Type GetInterface(String name, bool ignoreCase);
+
+
+ // GetInterfaces
+ // This method will return all of the interfaces implemented by a class
+ abstract public Type[] GetInterfaces();
+
+ // FindInterfaces
+ // This method will filter the interfaces supported the class
+ public virtual Type[] FindInterfaces(TypeFilter filter,Object filterCriteria)
+ {
+ if (filter == null)
+ throw new ArgumentNullException("filter");
+ Contract.EndContractBlock();
+ Type[] c = GetInterfaces();
+ int cnt = 0;
+ for (int i = 0;i<c.Length;i++) {
+ if (!filter(c[i],filterCriteria))
+ c[i] = null;
+ else
+ cnt++;
+ }
+ if (cnt == c.Length)
+ return c;
+
+ Type[] ret = new Type[cnt];
+ cnt=0;
+ for (int i=0;i<c.Length;i++) {
+ if (c[i] != null)
+ ret[cnt++] = c[i];
+ }
+ return ret;
+ }
+
+ // GetEvent
+ // This method will return a event by name if it is found.
+ // null is returned if the event is not found
+
+
+ public EventInfo GetEvent(String name) {
+ return GetEvent(name,Type.DefaultLookup);
+ }
+ abstract public EventInfo GetEvent(String name,BindingFlags bindingAttr);
+
+ // GetEvents
+ // This method will return an array of EventInfo. If there are not Events
+ // an empty array will be returned.
+ virtual public EventInfo[] GetEvents() {
+ return GetEvents(Type.DefaultLookup);
+ }
+ abstract public EventInfo[] GetEvents(BindingFlags bindingAttr);
+
+
+ // Return a property based upon the passed criteria. The nameof the
+ // parameter must be provided.
+ public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder,
+ Type returnType, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
+ }
+
+ public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
+ }
+
+ public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,bindingAttr,null,null,null,null);
+ }
+
+ public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
+ }
+
+ public PropertyInfo GetProperty(String name, Type[] types)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (types == null)
+ throw new ArgumentNullException("types");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
+ }
+
+ public PropertyInfo GetProperty(String name, Type returnType)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (returnType == null)
+ throw new ArgumentNullException("returnType");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
+ }
+
+ internal PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Type returnType)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (returnType == null)
+ throw new ArgumentNullException("returnType");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name, bindingAttr, null, returnType, null, null);
+ }
+
+ public PropertyInfo GetProperty(String name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ Contract.EndContractBlock();
+ return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
+ }
+
+ protected abstract PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr,Binder binder,
+ Type returnType, Type[] types, ParameterModifier[] modifiers);
+
+
+ // GetProperties
+ // This method will return an array of all of the properties defined
+ // for a Type.
+ abstract public PropertyInfo[] GetProperties(BindingFlags bindingAttr);
+ public PropertyInfo[] GetProperties()
+ {
+ return GetProperties(Type.DefaultLookup);
+ }
+#if !FEATURE_CORECLR
+#endif
+ // GetNestedTypes()
+ // This set of method will return any nested types that are found inside
+ // of the type.
+ public Type[] GetNestedTypes()
+ {
+ return GetNestedTypes(Type.DefaultLookup);
+ }
+
+ abstract public Type[] GetNestedTypes(BindingFlags bindingAttr);
+
+#if !FEATURE_CORECLR
+ // GetNestedType()
+#endif
+ public Type GetNestedType(String name)
+ {
+ return GetNestedType(name,Type.DefaultLookup);
+ }
+
+ abstract public Type GetNestedType(String name, BindingFlags bindingAttr);
+
+ // GetMember
+ // This method will return all of the members which match the specified string
+ // passed into the method
+ public MemberInfo[] GetMember(String name) {
+ return GetMember(name,Type.DefaultLookup);
+ }
+
+ virtual public MemberInfo[] GetMember(String name, BindingFlags bindingAttr)
+ {
+ return GetMember(name,MemberTypes.All,bindingAttr);
+ }
+
+ virtual public MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+
+ // GetMembers
+ // This will return a Member array of all of the members of a class
+ public MemberInfo[] GetMembers() {
+ return GetMembers(Type.DefaultLookup);
+ }
+ abstract public MemberInfo[] GetMembers(BindingFlags bindingAttr);
+
+ // GetDefaultMembers
+ // This will return a MemberInfo that has been marked with the
+ // DefaultMemberAttribute
+ public virtual MemberInfo[] GetDefaultMembers()
+ {
+ throw new NotImplementedException();
+ }
+
+ // FindMembers
+ // This will return a filtered version of the member information
+ public virtual MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria)
+ {
+ // Define the work arrays
+ MethodInfo[] m = null;
+ ConstructorInfo[] c = null;
+ FieldInfo[] f = null;
+ PropertyInfo[] p = null;
+ EventInfo[] e = null;
+ Type[] t = null;
+
+ int i = 0;
+ int cnt = 0; // Total Matchs
+
+ // Check the methods
+ if ((memberType & System.Reflection.MemberTypes.Method) != 0) {
+ m = GetMethods(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<m.Length;i++)
+ if (!filter(m[i],filterCriteria))
+ m[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=m.Length;
+ }
+ }
+
+ // Check the constructors
+ if ((memberType & System.Reflection.MemberTypes.Constructor) != 0) {
+ c = GetConstructors(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<c.Length;i++)
+ if (!filter(c[i],filterCriteria))
+ c[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=c.Length;
+ }
+ }
+
+ // Check the fields
+ if ((memberType & System.Reflection.MemberTypes.Field) != 0) {
+ f = GetFields(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<f.Length;i++)
+ if (!filter(f[i],filterCriteria))
+ f[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=f.Length;
+ }
+ }
+
+ // Check the Properties
+ if ((memberType & System.Reflection.MemberTypes.Property) != 0) {
+ p = GetProperties(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<p.Length;i++)
+ if (!filter(p[i],filterCriteria))
+ p[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=p.Length;
+ }
+ }
+
+ // Check the Events
+ if ((memberType & System.Reflection.MemberTypes.Event) != 0) {
+ e = GetEvents(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<e.Length;i++)
+ if (!filter(e[i],filterCriteria))
+ e[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=e.Length;
+ }
+ }
+
+ // Check the Types
+ if ((memberType & System.Reflection.MemberTypes.NestedType) != 0) {
+ t = GetNestedTypes(bindingAttr);
+ if (filter != null) {
+ for (i=0;i<t.Length;i++)
+ if (!filter(t[i],filterCriteria))
+ t[i] = null;
+ else
+ cnt++;
+ } else {
+ cnt+=t.Length;
+ }
+ }
+
+ // Allocate the Member Info
+ MemberInfo[] ret = new MemberInfo[cnt];
+
+ // Copy the Methods
+ cnt = 0;
+ if (m != null) {
+ for (i=0;i<m.Length;i++)
+ if (m[i] != null)
+ ret[cnt++] = m[i];
+ }
+
+ // Copy the Constructors
+ if (c != null) {
+ for (i=0;i<c.Length;i++)
+ if (c[i] != null)
+ ret[cnt++] = c[i];
+ }
+
+ // Copy the Fields
+ if (f != null) {
+ for (i=0;i<f.Length;i++)
+ if (f[i] != null)
+ ret[cnt++] = f[i];
+ }
+
+ // Copy the Properties
+ if (p != null) {
+ for (i=0;i<p.Length;i++)
+ if (p[i] != null)
+ ret[cnt++] = p[i];
+ }
+
+ // Copy the Events
+ if (e != null) {
+ for (i=0;i<e.Length;i++)
+ if (e[i] != null)
+ ret[cnt++] = e[i];
+ }
+
+ // Copy the Types
+ if (t != null) {
+ for (i=0;i<t.Length;i++)
+ if (t[i] != null)
+ ret[cnt++] = t[i];
+ }
+
+ return ret;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Attributes
+ //
+ // The attributes are all treated as read-only properties on a class. Most of
+ // these boolean properties have flag values defined in this class and act like
+ // a bit mask of attributes. There are also a set of boolean properties that
+ // relate to the classes relationship to other classes and to the state of the
+ // class inside the runtime.
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+
+ public bool IsNested
+ {
+ [Pure]
+ get
+ {
+ return DeclaringType != null;
+ }
+ }
+
+ // The attribute property on the Type.
+ public TypeAttributes Attributes {
+ [Pure]
+ get {return GetAttributeFlagsImpl();}
+ }
+
+ public virtual GenericParameterAttributes GenericParameterAttributes
+ {
+ get { throw new NotSupportedException(); }
+ }
+
+ public bool IsVisible
+ {
+ [Pure]
+ get
+ {
+ RuntimeType rt = this as RuntimeType;
+ if (rt != null)
+ return RuntimeTypeHandle.IsVisible(rt);
+
+ if (IsGenericParameter)
+ return true;
+
+ if (HasElementType)
+ return GetElementType().IsVisible;
+
+ Type type = this;
+ while (type.IsNested)
+ {
+ if (!type.IsNestedPublic)
+ return false;
+
+ // this should be null for non-nested types.
+ type = type.DeclaringType;
+ }
+
+ // Now "type" should be a top level type
+ if (!type.IsPublic)
+ return false;
+
+ if (IsGenericType && !IsGenericTypeDefinition)
+ {
+ foreach (Type t in GetGenericArguments())
+ {
+ if (!t.IsVisible)
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ public bool IsNotPublic
+ {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic);}
+ }
+
+ public bool IsPublic {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public);}
+ }
+
+ public bool IsNestedPublic {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic);}
+ }
+
+ public bool IsNestedPrivate {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate);}
+ }
+ public bool IsNestedFamily {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily);}
+ }
+ public bool IsNestedAssembly {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly);}
+ }
+ public bool IsNestedFamANDAssem {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem);}
+ }
+ public bool IsNestedFamORAssem{
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem);}
+ }
+
+ public bool IsAutoLayout {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout);}
+ }
+ public bool IsLayoutSequential {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout);}
+ }
+ public bool IsExplicitLayout {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout);}
+ }
+
+ public bool IsClass {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType);}
+ }
+
+ public bool IsInterface {
+ [Pure]
+ [System.Security.SecuritySafeCritical] // auto-generated
+ get
+ {
+ RuntimeType rt = this as RuntimeType;
+ if (rt != null)
+ return RuntimeTypeHandle.IsInterface(rt);
+
+ return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);
+ }
+ }
+
+ public bool IsValueType {
+ [Pure]
+ get {return IsValueTypeImpl();}
+ }
+
+ public bool IsAbstract {
+ [Pure]
+ get { return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0); }
+ }
+
+ public bool IsSealed {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
+ }
+
+#if FEATURE_CORECLR
+ public bool IsEnum {
+#else
+ public virtual bool IsEnum {
+#endif
+ [Pure]
+ get
+ {
+ // This will return false for a non-runtime Type object unless it overrides IsSubclassOf.
+ return IsSubclassOf(RuntimeType.EnumType);
+ }
+ }
+
+ public bool IsSpecialName {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0);}
+ }
+
+ public bool IsImport {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0);}
+ }
+
+ public virtual bool IsSerializable
+ {
+ [Pure]
+ get
+ {
+ if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0)
+ return true;
+
+ RuntimeType rt = this.UnderlyingSystemType as RuntimeType;
+
+ if (rt != null)
+ return rt.IsSpecialSerializableType();
+
+ return false;
+ }
+ }
+
+ public bool IsAnsiClass {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass);}
+ }
+
+ public bool IsUnicodeClass {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass);}
+ }
+
+ public bool IsAutoClass {
+ [Pure]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass);}
+ }
+
+ // These are not backed up by attributes. Instead they are implemented
+ // based internally.
+ public bool IsArray {
+ [Pure]
+ get {return IsArrayImpl();}
+ }
+
+ internal virtual bool IsSzArray {
+ [Pure]
+ get {return false;}
+ }
+
+ public virtual bool IsGenericType {
+ [Pure]
+ get { return false; }
+ }
+
+ public virtual bool IsGenericTypeDefinition {
+ [Pure]
+ get { return false; }
+ }
+
+ public virtual bool IsConstructedGenericType
+ {
+ [Pure]
+ get { throw new NotImplementedException(); }
+ }
+
+ public virtual bool IsGenericParameter
+ {
+ [Pure]
+ get { return false; }
+ }
+
+ public virtual int GenericParameterPosition {
+ [Pure]
+ get {throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter")); }
+ }
+
+ public virtual bool ContainsGenericParameters
+ {
+ [Pure]
+ get
+ {
+ if (HasElementType)
+ return GetRootElementType().ContainsGenericParameters;
+
+ if (IsGenericParameter)
+ return true;
+
+ if (!IsGenericType)
+ return false;
+
+ Type[] genericArguments = GetGenericArguments();
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ if (genericArguments[i].ContainsGenericParameters)
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ [Pure]
+ public virtual Type[] GetGenericParameterConstraints()
+ {
+ if (!IsGenericParameter)
+ throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ Contract.EndContractBlock();
+
+ throw new InvalidOperationException();
+ }
+
+ public bool IsByRef {
+ [Pure]
+ get {return IsByRefImpl();}
+ }
+ public bool IsPointer {
+ [Pure]
+ get {return IsPointerImpl();}
+ }
+ public bool IsPrimitive {
+ [Pure]
+ get {return IsPrimitiveImpl();}
+ }
+ public bool IsCOMObject {
+ [Pure]
+ get {return IsCOMObjectImpl();}
+ }
+
+#if FEATURE_COMINTEROP
+ internal bool IsWindowsRuntimeObject {
+ [Pure]
+ get { return IsWindowsRuntimeObjectImpl(); }
+ }
+
+ internal bool IsExportedToWindowsRuntime {
+ [Pure]
+ get { return IsExportedToWindowsRuntimeImpl(); }
+ }
+#endif // FEATURE_COMINTEROP
+
+ public bool HasElementType {
+ [Pure]
+ get {return HasElementTypeImpl();}
+ }
+
+ public bool IsContextful {
+ [Pure]
+ get {return IsContextfulImpl();}
+ }
+
+ public bool IsMarshalByRef {
+ [Pure]
+ get {return IsMarshalByRefImpl();}
+ }
+
+ internal bool HasProxyAttribute {
+ [Pure]
+ get {return HasProxyAttributeImpl();}
+ }
+
+ // Protected routine to determine if this class represents a value class
+ // The default implementation of IsValueTypeImpl never returns true for non-runtime types.
+ protected virtual bool IsValueTypeImpl()
+ {
+ // Note that typeof(Enum) and typeof(ValueType) are not themselves value types.
+ // But there is no point excluding them here because customer derived System.Type
+ // (non-runtime type) objects can never be equal to a runtime type, which typeof(XXX) is.
+ // Ideally we should throw a NotImplementedException here or just return false because
+ // customer implementations of IsSubclassOf should never return true between a non-runtime
+ // type and a runtime type. There is no benefits in making that breaking change though.
+
+ return IsSubclassOf(RuntimeType.ValueType);
+ }
+
+ // Protected routine to get the attributes.
+ abstract protected TypeAttributes GetAttributeFlagsImpl();
+
+ // Protected routine to determine if this class represents an Array
+ abstract protected bool IsArrayImpl();
+
+ // Protected routine to determine if this class is a ByRef
+ abstract protected bool IsByRefImpl();
+
+ // Protected routine to determine if this class is a Pointer
+ abstract protected bool IsPointerImpl();
+
+ // Protected routine to determine if this class represents a primitive type
+ abstract protected bool IsPrimitiveImpl();
+
+ // Protected routine to determine if this class represents a COM object
+ abstract protected bool IsCOMObjectImpl();
+
+#if FEATURE_COMINTEROP
+ // Protected routine to determine if this class represents a Windows Runtime object
+ virtual internal bool IsWindowsRuntimeObjectImpl() {
+ throw new NotImplementedException();
+ }
+
+ // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd)
+ virtual internal bool IsExportedToWindowsRuntimeImpl() {
+ throw new NotImplementedException();
+ }
+#endif // FEATURE_COMINTEROP
+
+ public virtual Type MakeGenericType(params Type[] typeArguments) {
+ Contract.Ensures(Contract.Result<Type>() != null);
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+
+ // Protected routine to determine if this class is contextful
+ protected virtual bool IsContextfulImpl(){
+ return typeof(ContextBoundObject).IsAssignableFrom(this);
+ }
+
+
+ // Protected routine to determine if this class is marshaled by ref
+ protected virtual bool IsMarshalByRefImpl(){
+ return typeof(MarshalByRefObject).IsAssignableFrom(this);
+ }
+
+ internal virtual bool HasProxyAttributeImpl()
+ {
+ // We will override this in RuntimeType
+ return false;
+ }
+
+ [Pure]
+ abstract public Type GetElementType();
+
+ [Pure]
+ public virtual Type[] GetGenericArguments()
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+ public virtual Type[] GenericTypeArguments{
+ get{
+ if(IsGenericType && !IsGenericTypeDefinition){
+ return GetGenericArguments();
+ }
+ else{
+ return Type.EmptyTypes;
+ }
+
+ }
+ }
+
+ [Pure]
+ public virtual Type GetGenericTypeDefinition()
+ {
+ Contract.Ensures(Contract.Result<Type>() != null);
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+ [Pure]
+ abstract protected bool HasElementTypeImpl();
+
+ internal Type GetRootElementType()
+ {
+ Type rootElementType = this;
+
+ while (rootElementType.HasElementType)
+ rootElementType = rootElementType.GetElementType();
+
+ return rootElementType;
+ }
+
+ #region Enum methods
+
+ // Default implementations of GetEnumNames, GetEnumValues, and GetEnumUnderlyingType
+ // Subclass of types can override these methods.
+
+ public virtual string[] GetEnumNames()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ Contract.Ensures(Contract.Result<String[]>() != null);
+
+ string[] names;
+ Array values;
+ GetEnumData(out names, out values);
+ return names;
+ }
+
+ // We don't support GetEnumValues in the default implementation because we cannot create an array of
+ // a non-runtime type. If there is strong need we can consider returning an object or int64 array.
+ public virtual Array GetEnumValues()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ Contract.Ensures(Contract.Result<Array>() != null);
+
+ throw new NotImplementedException();
+ }
+
+ // Returns the enum values as an object array.
+ private Array GetEnumRawConstantValues()
+ {
+ string[] names;
+ Array values;
+ GetEnumData(out names, out values);
+ return values;
+ }
+
+ // This will return enumValues and enumNames sorted by the values.
+ private void GetEnumData(out string[] enumNames, out Array enumValues)
+ {
+ Contract.Ensures(Contract.ValueAtReturn<String[]>(out enumNames) != null);
+ Contract.Ensures(Contract.ValueAtReturn<Array>(out enumValues) != null);
+
+ FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
+
+ object[] values = new object[flds.Length];
+ string[] names = new string[flds.Length];
+
+ for (int i = 0; i < flds.Length; i++)
+ {
+ names[i] = flds[i].Name;
+ values[i] = flds[i].GetRawConstantValue();
+ }
+
+ // Insertion Sort these values in ascending order.
+ // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
+ // the common case performance will be faster than quick sorting this.
+ IComparer comparer = Comparer.Default;
+ for (int i = 1; i < values.Length; i++)
+ {
+ int j = i;
+ string tempStr = names[i];
+ object val = values[i];
+ bool exchanged = false;
+
+ // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
+ while (comparer.Compare(values[j - 1], val) > 0)
+ {
+ names[j] = names[j - 1];
+ values[j] = values[j - 1];
+ j--;
+ exchanged = true;
+ if (j == 0)
+ break;
+ }
+
+ if (exchanged)
+ {
+ names[j] = tempStr;
+ values[j] = val;
+ }
+ }
+
+ enumNames = names;
+ enumValues = values;
+ }
+
+ public virtual Type GetEnumUnderlyingType()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ Contract.Ensures(Contract.Result<Type>() != null);
+
+ FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ if (fields == null || fields.Length != 1)
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnum"), "enumType");
+
+ return fields[0].FieldType;
+ }
+
+ public virtual bool IsEnumDefined(object value)
+ {
+ if (value == null)
+ throw new ArgumentNullException("value");
+
+ if (!IsEnum)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ Contract.EndContractBlock();
+
+ // Check if both of them are of the same type
+ Type valueType = value.GetType();
+
+ // If the value is an Enum then we need to extract the underlying value from it
+ if (valueType.IsEnum)
+ {
+ if (!valueType.IsEquivalentTo(this))
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
+
+ valueType = valueType.GetEnumUnderlyingType();
+ }
+
+ // If a string is passed in
+ if (valueType == typeof(string))
+ {
+ string[] names = GetEnumNames();
+ if (Array.IndexOf(names, value) >= 0)
+ return true;
+ else
+ return false;
+ }
+
+ // If an enum or integer value is passed in
+ if (Type.IsIntegerType(valueType))
+ {
+ Type underlyingType = GetEnumUnderlyingType();
+ // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
+ if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
+
+ Array values = GetEnumRawConstantValues();
+ return (BinarySearch(values, value) >= 0);
+ }
+ else
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ }
+ }
+
+ public virtual string GetEnumName(object value)
+ {
+ if (value == null)
+ throw new ArgumentNullException("value");
+
+ if (!IsEnum)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ Contract.EndContractBlock();
+
+ Type valueType = value.GetType();
+
+ if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
+
+ Array values = GetEnumRawConstantValues();
+ int index = BinarySearch(values, value);
+
+ if (index >= 0)
+ {
+ string[] names = GetEnumNames();
+ return names[index];
+ }
+
+ return null;
+ }
+
+ // Convert everything to ulong then perform a binary search.
+ private static int BinarySearch(Array array, object value)
+ {
+ ulong[] ulArray = new ulong[array.Length];
+ for (int i = 0; i < array.Length; ++i)
+ ulArray[i] = Enum.ToUInt64(array.GetValue(i));
+
+ ulong ulValue = Enum.ToUInt64(value);
+
+ return Array.BinarySearch(ulArray, ulValue);
+ }
+
+ internal static bool IsIntegerType(Type t)
+ {
+ return (t == typeof(int) ||
+ t == typeof(short) ||
+ t == typeof(ushort) ||
+ t == typeof(byte) ||
+ t == typeof(sbyte) ||
+ t == typeof(uint) ||
+ t == typeof(long) ||
+ t == typeof(ulong) ||
+ t == typeof(char) ||
+ t == typeof(bool));
+ }
+ #endregion
+
+ public virtual bool IsSecurityCritical { [Pure] get { throw new NotImplementedException(); } }
+
+ public virtual bool IsSecuritySafeCritical { [Pure] get { throw new NotImplementedException(); } }
+
+ public virtual bool IsSecurityTransparent { [Pure] get { throw new NotImplementedException(); } }
+
+ internal bool NeedsReflectionSecurityCheck
+ {
+ get
+ {
+ if (!IsVisible)
+ {
+ // Types which are not externally visible require security checks
+ return true;
+ }
+ else if (IsSecurityCritical && !IsSecuritySafeCritical)
+ {
+ // Critical types require security checks
+ return true;
+ }
+ else if (IsGenericType)
+ {
+ // If any of the generic arguments to this type require a security check, then this type
+ // also requires one.
+ foreach (Type genericArgument in GetGenericArguments())
+ {
+ if (genericArgument.NeedsReflectionSecurityCheck)
+ {
+ return true;
+ }
+ }
+ }
+ else if (IsArray || IsPointer)
+ {
+ return GetElementType().NeedsReflectionSecurityCheck;
+ }
+
+ return false;
+ }
+ }
+
+ // The behavior of UnderlyingSystemType varies from type to type.
+ // For IReflect objects: Return the underlying Type that represents the IReflect Object.
+ // For expando object: this is the (Object) IReflectInstance.GetType(). For Type object it is this.
+ // It could also return the baked type or the underlying enum type in RefEmit. See the comment in
+ // code:TypeBuilder.SetConstantValue.
+ public abstract Type UnderlyingSystemType {
+ get;
+ }
+
+ // Returns true of this class is a true subclass of c. Everything
+ // else returns false. If this class and c are the same class false is
+ // returned.
+ //
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Pure]
+ public virtual bool IsSubclassOf(Type c)
+ {
+ Type p = this;
+ if (p == c)
+ return false;
+ while (p != null) {
+ if (p == c)
+ return true;
+ p = p.BaseType;
+ }
+ return false;
+ }
+
+ // Returns true if the object passed is assignable to an instance of this class.
+ // Everything else returns false.
+ //
+ [Pure]
+ public virtual bool IsInstanceOfType(Object o)
+ {
+ if (o == null)
+ return false;
+
+ // No need for transparent proxy casting check here
+ // because it never returns true for a non-rutnime type.
+
+ return IsAssignableFrom(o.GetType());
+ }
+
+ // Returns true if an instance of Type c may be assigned
+ // to an instance of this class. Return false otherwise.
+ //
+ [Pure]
+ public virtual bool IsAssignableFrom(Type c)
+ {
+ if (c == null)
+ return false;
+
+ if (this == c)
+ return true;
+
+ // For backward-compatibility, we need to special case for the types
+ // whose UnderlyingSystemType are RuntimeType objects.
+ RuntimeType toType = this.UnderlyingSystemType as RuntimeType;
+ if (toType != null)
+ return toType.IsAssignableFrom(c);
+
+ // If c is a subclass of this class, then c can be cast to this type.
+ if (c.IsSubclassOf(this))
+ return true;
+
+ if (this.IsInterface)
+ {
+ return c.ImplementInterface(this);
+ }
+ else if (IsGenericParameter)
+ {
+ Type[] constraints = GetGenericParameterConstraints();
+ for (int i = 0; i < constraints.Length; i++)
+ if (!constraints[i].IsAssignableFrom(c))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ // Base implementation that does only ==.
+ [Pure]
+ public virtual bool IsEquivalentTo(Type other)
+ {
+ return (this == other);
+ }
+
+ internal bool ImplementInterface(Type ifaceType)
+ {
+ Contract.Requires(ifaceType != null);
+ Contract.Requires(ifaceType.IsInterface, "ifaceType must be an interface type");
+
+ Type t = this;
+ while (t != null)
+ {
+ Type[] interfaces = t.GetInterfaces();
+ if (interfaces != null)
+ {
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ // Interfaces don't derive from other interfaces, they implement them.
+ // So instead of IsSubclassOf, we should use ImplementInterface instead.
+ if (interfaces[i] == ifaceType ||
+ (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType)))
+ return true;
+ }
+ }
+
+ t = t.BaseType;
+ }
+
+ return false;
+ }
+
+ // This is only ever called on RuntimeType objects.
+ internal string FormatTypeName()
+ {
+ return FormatTypeName(false);
+ }
+
+ internal virtual string FormatTypeName(bool serialization)
+ {
+ throw new NotImplementedException();
+ }
+
+ // ToString
+ // Print the String Representation of the Type
+ public override String ToString()
+ {
+ // Why do we add the "Type: " prefix? RuntimeType.ToString() doesn't include it.
+ return "Type: " + Name;
+ }
+
+ // This method will return an array of classes based upon the array of
+ // types.
+ public static Type[] GetTypeArray(Object[] args) {
+ if (args == null)
+ throw new ArgumentNullException("args");
+ Contract.EndContractBlock();
+ Type[] cls = new Type[args.Length];
+ for (int i = 0;i < cls.Length;i++)
+ {
+ if (args[i] == null)
+ throw new ArgumentNullException();
+ cls[i] = args[i].GetType();
+ }
+ return cls;
+ }
+
+ [Pure]
+ public override bool Equals(Object o)
+ {
+ if (o == null)
+ return false;
+
+ return Equals(o as Type);
+ }
+
+ // _Type.Equals(Type)
+ [Pure]
+#if !FEATURE_CORECLR
+ public virtual bool Equals(Type o)
+#else
+ public bool Equals(Type o)
+#endif
+ {
+ if ((object)o == null)
+ return false;
+
+ return (Object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType));
+ }
+
+ [System.Security.SecuritySafeCritical]
+ [Pure]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool operator ==(Type left, Type right);
+
+ [System.Security.SecuritySafeCritical]
+ [Pure]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool operator !=(Type left, Type right);
+
+ public override int GetHashCode()
+ {
+ Type SystemType = UnderlyingSystemType;
+ if (!Object.ReferenceEquals(SystemType, this))
+ return SystemType.GetHashCode();
+ return base.GetHashCode();
+ }
+
+
+ // GetInterfaceMap
+ // This method will return an interface mapping for the interface
+ // requested. It will throw an argument exception if the Type doesn't
+ // implemenet the interface.
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ }
+
+ // this method is required so Object.GetType is not made virtual by the compiler
+ // _Type.GetType()
+ public new Type GetType()
+ {
+ return base.GetType();
+ }
+
+#if !FEATURE_CORECLR
+ void _Type.GetTypeInfoCount(out uint pcTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _Type.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _Type.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ {
+ throw new NotImplementedException();
+ }
+
+ // If you implement this method, make sure to include _Type.Invoke in VM\DangerousAPIs.h and
+ // include _Type in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
+ void _Type.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ {
+ throw new NotImplementedException();
+ }
+#endif
+
+ // private convenience data
+ private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+ internal const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
+}
+}