Move Type.cs and Module.cs to Shared Partition.
authorAtsushi Kanamori <atsushik@microsoft.com>
Mon, 20 Mar 2017 17:42:17 +0000 (10:42 -0700)
committerdotnet-bot <dotnet-bot@microsoft.com>
Mon, 20 Mar 2017 21:09:50 +0000 (21:09 +0000)
Types.cs is split into the main file, Type.Helpers.cs and Type.Enum.cs.
All three will be shared.

- GenericTypeArguments - reconcile with CoreClr
  (the code is identical provided that the underlying
  Type provider implemented IsConstructedGenericType
  correctly. But we can't assume that for third party types.)

- IsInterface and IsSerializable has some CoreClr
  specific logic for RuntimeTypes - moving this out
  to the unshared space for now.

- IsContextFulImpl()/IsMarshalByRefImpl() - corrected
  implemention to match CoreClr.

- IsIntegerType - no CommonRuntimeTypes in CoreClr
  so going back to typeof() checks - the runtime implemented
  types override all this enum code anyway on both runtimes.

- GetRootElementType() - upgraded visibility to "internal"
  as a concession to CoreClr.

- CoreCLR's IsVisible has a fast path - we'll keep that.

- Moved IsRuntimeImplemented() out of Internal.Reflection.Core.NonPortable
  namespace so calls to it can be more easily shared.

- Module.MethodHandle was not implemented correctly for
  non-runtime modules (it's supposed to return default(ModuleHandle)).
  This makes it behave correctly and reconciles Module.cs
  with the CoreCLR version.

src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
src/mscorlib/shared/System/Reflection/Module.cs [new file with mode: 0644]
src/mscorlib/shared/System/Type.Enum.cs [new file with mode: 0644]
src/mscorlib/shared/System/Type.Helpers.cs [new file with mode: 0644]
src/mscorlib/shared/System/Type.cs [new file with mode: 0644]

index 8286d37..fd12c72 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MemberInfo.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodInfo.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodBase.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Module.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ObfuscateAssemblyAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ObfuscationAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ParameterInfo.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\TimeoutException.cs"/>
     <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneNotFoundException.cs"/>
     <Compile Include="$(MSBuildThisFileDirectory)System\TupleExtensions.cs"/>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Type.cs"/>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Type.Enum.cs"/>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Type.Helpers.cs"/>
     <Compile Include="$(MSBuildThisFileDirectory)System\TypeAccessException.cs"/>
     <Compile Include="$(MSBuildThisFileDirectory)System\TypeCode.cs"/>
     <Compile Include="$(MSBuildThisFileDirectory)System\TypeInitializationException.cs"/>
diff --git a/src/mscorlib/shared/System/Reflection/Module.cs b/src/mscorlib/shared/System/Reflection/Module.cs
new file mode 100644 (file)
index 0000000..56f83c4
--- /dev/null
@@ -0,0 +1,182 @@
+// 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.
+
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace System.Reflection
+{
+    public abstract class Module : ICustomAttributeProvider, ISerializable
+    {
+        protected Module() { }
+
+        public virtual Assembly Assembly { get { throw NotImplemented.ByDesign; } }
+        public virtual string FullyQualifiedName { get { throw NotImplemented.ByDesign; } }
+        public virtual string Name { get { throw NotImplemented.ByDesign; } }
+
+        public virtual int MDStreamVersion { get { throw NotImplemented.ByDesign; } }
+        public virtual Guid ModuleVersionId { get { throw NotImplemented.ByDesign; } }
+        public virtual string ScopeName { get { throw NotImplemented.ByDesign; } }
+        public ModuleHandle ModuleHandle => GetModuleHandleImpl();
+        protected virtual ModuleHandle GetModuleHandleImpl() => ModuleHandle.EmptyHandle; // Not an api but declared protected because of Reflection.Core/Corelib divide (when built by CoreRt)
+        public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) { throw NotImplemented.ByDesign; }
+        public virtual bool IsResource() { throw NotImplemented.ByDesign; }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+        public virtual IEnumerable<CustomAttributeData> CustomAttributes => GetCustomAttributesData();
+        public virtual IList<CustomAttributeData> GetCustomAttributesData() { throw NotImplemented.ByDesign; }
+        public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+
+        public MethodInfo GetMethod(string name)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+
+            return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any, null, null);
+        }
+
+        public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, Module.DefaultLookup, null, CallingConventions.Any, types, null);
+        public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            if (types == null)
+                throw new ArgumentNullException(nameof(types));
+            for (int i = 0; i < types.Length; i++)
+            {
+                if (types[i] == null)
+                    throw new ArgumentNullException(nameof(types));
+            }
+            return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
+        }
+
+        protected virtual MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw NotImplemented.ByDesign; }
+
+        public MethodInfo[] GetMethods() => GetMethods(Module.DefaultLookup);
+        public virtual MethodInfo[] GetMethods(BindingFlags bindingFlags) { throw NotImplemented.ByDesign; }
+
+        public FieldInfo GetField(string name) => GetField(name, Module.DefaultLookup);
+        public virtual FieldInfo GetField(string name, BindingFlags bindingAttr) { throw NotImplemented.ByDesign; }
+
+        public FieldInfo[] GetFields() => GetFields(Module.DefaultLookup);
+        public virtual FieldInfo[] GetFields(BindingFlags bindingFlags) { throw NotImplemented.ByDesign; }
+
+        public virtual Type[] GetTypes() { throw NotImplemented.ByDesign; }
+
+        public virtual Type GetType(string className) => GetType(className, throwOnError: false, ignoreCase: false);
+        public virtual Type GetType(string className, bool ignoreCase) => GetType(className, throwOnError: false, ignoreCase: ignoreCase);
+        public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) { throw NotImplemented.ByDesign; }
+
+        public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria)
+        {
+            Type[] c = GetTypes();
+            int cnt = 0;
+            for (int i = 0; i < c.Length; i++)
+            {
+                if (filter != null && !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;
+        }
+
+        public virtual int MetadataToken { get { throw NotImplemented.ByDesign; } }
+
+        public FieldInfo ResolveField(int metadataToken) => ResolveField(metadataToken, null, null);
+        public virtual FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+        public MemberInfo ResolveMember(int metadataToken) => ResolveMember(metadataToken, null, null);
+        public virtual MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+        public MethodBase ResolveMethod(int metadataToken) => ResolveMethod(metadataToken, null, null);
+        public virtual MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+        public virtual byte[] ResolveSignature(int metadataToken) { throw NotImplemented.ByDesign; }
+        public virtual string ResolveString(int metadataToken) { throw NotImplemented.ByDesign; }
+
+        public Type ResolveType(int metadataToken) => ResolveType(metadataToken, null, null);
+        public virtual Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+        public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; }
+
+        public override bool Equals(object o) => base.Equals(o);
+        public override int GetHashCode() => base.GetHashCode();
+
+        public static bool operator ==(Module left, Module right)
+        {
+            if (object.ReferenceEquals(left, right))
+                return true;
+
+            if ((object)left == null || (object)right == null)
+                return false;
+
+            return left.Equals(right);
+        }
+
+        public static bool operator !=(Module left, Module right) => !(left == right);
+
+        public override string ToString() => ScopeName;
+
+        public static readonly TypeFilter FilterTypeName = FilterTypeNameImpl;
+        public static readonly TypeFilter FilterTypeNameIgnoreCase = FilterTypeNameIgnoreCaseImpl;
+
+        private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+
+        // FilterTypeName 
+        // This method will filter the class based upon the name.  It supports
+        //    a trailing wild card.
+        private static bool FilterTypeNameImpl(Type cls, object filterCriteria)
+        {
+            // Check that the criteria object is a String object
+            if (filterCriteria == null || !(filterCriteria is string))
+                throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+            string str = (string)filterCriteria;
+
+            // Check to see if this is a prefix or exact match requirement
+            if (str.Length > 0 && str[str.Length - 1] == '*')
+            {
+                str = str.Substring(0, str.Length - 1);
+                return cls.Name.StartsWith(str, StringComparison.Ordinal);
+            }
+
+            return cls.Name.Equals(str);
+        }
+
+        // FilterFieldNameIgnoreCase
+        // This method filter the Type based upon name, it ignores case.
+        private static bool FilterTypeNameIgnoreCaseImpl(Type cls, object filterCriteria)
+        {
+            // Check that the criteria object is a String object
+            if (filterCriteria == null || !(filterCriteria is string))
+                throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+            string str = (string)filterCriteria;
+
+            // Check to see if this is a prefix or exact match requirement
+            if (str.Length > 0 && str[str.Length - 1] == '*')
+            {
+                str = str.Substring(0, str.Length - 1);
+                string name = cls.Name;
+                if (name.Length >= str.Length)
+                    return (string.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0);
+                else
+                    return false;
+            }
+            return (string.Compare(str, cls.Name, StringComparison.OrdinalIgnoreCase) == 0);
+        }
+    }
+}
diff --git a/src/mscorlib/shared/System/Type.Enum.cs b/src/mscorlib/shared/System/Type.Enum.cs
new file mode 100644 (file)
index 0000000..4d82410
--- /dev/null
@@ -0,0 +1,186 @@
+// 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.
+
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System
+{
+    //
+    // This file collects a set of Enum-related apis that run when the Type is subclassed by an application.
+    // None of it runs on normal Type objects supplied by the runtime (as those types override these methods.)
+    //
+    // Since app-subclassed Types are "untrusted classes" that may or may not implement the complete surface area correctly,
+    // this code should be considered brittle and not changed lightly.
+    //
+    public abstract partial class Type
+    {
+        public virtual bool IsEnumDefined(object value)
+        {
+            if (value == null)
+                throw new ArgumentNullException(nameof(value));
+
+            if (!IsEnum)
+                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+            // 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(SR.Format(SR.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(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
+
+                Array values = GetEnumRawConstantValues();
+                return (BinarySearch(values, value) >= 0);
+            }
+            else
+            {
+                throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
+            }
+        }
+
+        public virtual string GetEnumName(object value)
+        {
+            if (value == null)
+                throw new ArgumentNullException(nameof(value));
+
+            if (!IsEnum)
+                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+            Type valueType = value.GetType();
+
+            if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
+                throw new ArgumentException(SR.Arg_MustBeEnumBaseTypeOrEnum, nameof(value));
+
+            Array values = GetEnumRawConstantValues();
+            int index = BinarySearch(values, value);
+
+            if (index >= 0)
+            {
+                string[] names = GetEnumNames();
+                return names[index];
+            }
+
+            return null;
+        }
+
+        public virtual string[] GetEnumNames()
+        {
+            if (!IsEnum)
+                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+            string[] names;
+            Array values;
+            GetEnumData(out names, out values);
+            return names;
+        }
+
+
+        // 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)
+        {
+            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<object>.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;
+        }
+
+        // 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));
+        }
+    }
+}
diff --git a/src/mscorlib/shared/System/Type.Helpers.cs b/src/mscorlib/shared/System/Type.Helpers.cs
new file mode 100644 (file)
index 0000000..f2f3bf6
--- /dev/null
@@ -0,0 +1,499 @@
+// 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.
+
+using System.Reflection;
+
+namespace System
+{
+    // This file collects the longer methods of Type to make the main Type class more readable.
+    public abstract partial class Type : MemberInfo, IReflect
+    {
+        public virtual bool ContainsGenericParameters
+        {
+            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;
+            }
+        }
+
+        internal Type GetRootElementType()
+        {
+            Type rootElementType = this;
+
+            while (rootElementType.HasElementType)
+                rootElementType = rootElementType.GetElementType();
+
+            return rootElementType;
+        }
+
+        public bool IsVisible
+        {
+            get
+            {
+#if CORECLR
+                RuntimeType rt = this as RuntimeType;
+                if (rt != null)
+                    return RuntimeTypeHandle.IsVisible(rt);
+#endif //CORECLR
+
+                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 virtual Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            if (filter == null)
+                throw new ArgumentNullException(nameof(filter));
+
+            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;
+        }
+
+        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 & 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 & 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 & 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 & 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 & 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 & 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;
+        }
+
+        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;
+        }
+
+        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 runtime implemented. 
+            Type toType = this.UnderlyingSystemType;
+            if (toType.IsRuntimeImplemented())
+                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;
+        }
+
+        internal bool ImplementInterface(Type ifaceType)
+        {
+            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;
+        }
+
+        // FilterAttribute
+        //  This method will search for a member based upon the attribute passed in.
+        //  filterCriteria -- an Int32 representing the attribute
+        private static bool FilterAttributeImpl(MemberInfo m, object filterCriteria)
+        {
+            // Check that the criteria object is an Integer object
+            if (filterCriteria == null)
+                throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+
+            switch (m.MemberType)
+            {
+                case MemberTypes.Constructor:
+                case MemberTypes.Method:
+                    {
+                        MethodAttributes criteria = 0;
+                        try
+                        {
+                            int i = (int)filterCriteria;
+                            criteria = (MethodAttributes)i;
+                        }
+                        catch
+                        {
+                            throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+                        }
+
+
+                        MethodAttributes attr;
+                        if (m.MemberType == MemberTypes.Method)
+                            attr = ((MethodInfo)m).Attributes;
+                        else
+                            attr = ((ConstructorInfo)m).Attributes;
+
+                        if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask))
+                            return false;
+                        if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0)
+                            return false;
+                        if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0)
+                            return false;
+                        if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0)
+                            return false;
+                        if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0)
+                            return false;
+                        if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0)
+                            return false;
+                        return true;
+                    }
+                case MemberTypes.Field:
+                    {
+                        FieldAttributes criteria = 0;
+                        try
+                        {
+                            int i = (int)filterCriteria;
+                            criteria = (FieldAttributes)i;
+                        }
+                        catch
+                        {
+                            throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+                        }
+
+                        FieldAttributes attr = ((FieldInfo)m).Attributes;
+                        if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask))
+                            return false;
+                        if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0)
+                            return false;
+                        if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0)
+                            return false;
+                        if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0)
+                            return false;
+                        if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0)
+                            return false;
+                        if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0)
+                            return false;
+                        return true;
+                    }
+            }
+
+            return false;
+        }
+
+        // FilterName
+        // This method will filter based upon the name.  A partial wildcard
+        //  at the end of the string is supported.
+        //  filterCriteria -- This is the string name
+        private static bool FilterNameImpl(MemberInfo m, object filterCriteria)
+        {
+            // Check that the criteria object is a String object
+            if (filterCriteria == null || !(filterCriteria is string))
+                throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+            // At the moment this fails if its done on a single line....
+            string str = ((string)filterCriteria);
+            str = str.Trim();
+
+            string name = m.Name;
+            // Get the nested class name only, as opposed to the mangled one
+            if (m.MemberType == MemberTypes.NestedType)
+                name = name.Substring(name.LastIndexOf('+') + 1);
+            // Check to see if this is a prefix or exact match requirement
+            if (str.Length > 0 && str[str.Length - 1] == '*')
+            {
+                str = str.Substring(0, str.Length - 1);
+                return (name.StartsWith(str, StringComparison.Ordinal));
+            }
+
+            return (name.Equals(str));
+        }
+
+        // FilterIgnoreCase
+        // This delegate will do a name search but does it with the
+        //  ignore case specified.
+        private static bool FilterNameIgnoreCaseImpl(MemberInfo m, object filterCriteria)
+        {
+            // Check that the criteria object is a String object
+            if (filterCriteria == null || !(filterCriteria is string))
+                throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+            string str = (string)filterCriteria;
+            str = str.Trim();
+
+            string name = m.Name;
+            // Get the nested class name only, as opposed to the mangled one
+            if (m.MemberType == MemberTypes.NestedType)
+                name = name.Substring(name.LastIndexOf('+') + 1);
+            // Check to see if this is a prefix or exact match requirement
+            if (str.Length > 0 && str[str.Length - 1] == '*')
+            {
+                str = str.Substring(0, str.Length - 1);
+                return (string.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0);
+            }
+
+            return (string.Compare(str, name, StringComparison.OrdinalIgnoreCase) == 0);
+        }
+    }
+}
+
diff --git a/src/mscorlib/shared/System/Type.cs b/src/mscorlib/shared/System/Type.cs
new file mode 100644 (file)
index 0000000..09a72aa
--- /dev/null
@@ -0,0 +1,341 @@
+// 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.
+
+using System.Reflection;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+    public abstract partial class Type : MemberInfo, IReflect
+    {
+        protected Type() { }
+
+        public override MemberTypes MemberType => MemberTypes.TypeInfo;
+
+        public new Type GetType() => base.GetType();
+
+        public abstract string Namespace { get; }
+        public abstract string AssemblyQualifiedName { get; }
+        public abstract string FullName { get; }
+
+        public abstract Assembly Assembly { get; }
+        public abstract new Module Module { get; }
+
+        public bool IsNested => DeclaringType != null;
+        public override Type DeclaringType => null;
+        public virtual MethodBase DeclaringMethod => null;
+
+        public override Type ReflectedType => null;
+        public abstract Type UnderlyingSystemType { get; }
+
+        public bool IsArray => IsArrayImpl();
+        protected abstract bool IsArrayImpl();
+        public bool IsByRef => IsByRefImpl();
+        protected abstract bool IsByRefImpl();
+        public bool IsPointer => IsPointerImpl();
+        protected abstract bool IsPointerImpl();
+        public virtual bool IsConstructedGenericType { get { throw NotImplemented.ByDesign; } }
+        public virtual bool IsGenericParameter => false;
+        public virtual bool IsGenericType => false;
+        public virtual bool IsGenericTypeDefinition => false;
+
+        public virtual bool IsSZArray { get { throw NotImplemented.ByDesign; } }
+
+        public bool HasElementType => HasElementTypeImpl();
+        protected abstract bool HasElementTypeImpl();
+        public abstract Type GetElementType();
+
+        public virtual int GetArrayRank() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+        public virtual Type GetGenericTypeDefinition() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+        public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : Array.Empty<Type>();
+        public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+        public virtual int GenericParameterPosition { get { throw new InvalidOperationException(SR.Arg_NotGenericParameter); } }
+        public virtual GenericParameterAttributes GenericParameterAttributes { get { throw new NotSupportedException(); } }
+        public virtual Type[] GetGenericParameterConstraints()
+        {
+            if (!IsGenericParameter)
+                throw new InvalidOperationException(SR.Arg_NotGenericParameter);
+            throw new InvalidOperationException();
+        }
+
+        public TypeAttributes Attributes => GetAttributeFlagsImpl();
+        protected abstract TypeAttributes GetAttributeFlagsImpl();
+
+        public bool IsAbstract => (GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0;
+        public bool IsImport => (GetAttributeFlagsImpl() & TypeAttributes.Import) != 0;
+        public bool IsSealed => (GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0;
+        public bool IsSpecialName => (GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0;
+
+        public bool IsClass => (GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType;
+
+        public bool IsNestedAssembly => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
+        public bool IsNestedFamANDAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
+        public bool IsNestedFamily => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
+        public bool IsNestedFamORAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
+        public bool IsNestedPrivate => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
+        public bool IsNestedPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
+        public bool IsNotPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
+        public bool IsPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
+
+        public bool IsAutoLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
+        public bool IsExplicitLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
+        public bool IsLayoutSequential => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
+
+        public bool IsAnsiClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass;
+        public bool IsAutoClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
+        public bool IsUnicodeClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
+
+        public bool IsCOMObject => IsCOMObjectImpl();
+        protected abstract bool IsCOMObjectImpl();
+        public bool IsContextful => IsContextfulImpl();
+        protected virtual bool IsContextfulImpl() => false;
+
+        public virtual bool IsEnum => IsSubclassOf(typeof(Enum));
+        public bool IsMarshalByRef => IsMarshalByRefImpl();
+        protected virtual bool IsMarshalByRefImpl() => false;
+        public bool IsPrimitive => IsPrimitiveImpl();
+        protected abstract bool IsPrimitiveImpl();
+        public bool IsValueType => IsValueTypeImpl();
+        protected virtual bool IsValueTypeImpl() => IsSubclassOf(typeof(ValueType));
+
+        public virtual bool IsSecurityCritical { get { throw NotImplemented.ByDesign; } }
+        public virtual bool IsSecuritySafeCritical { get { throw NotImplemented.ByDesign; } }
+        public virtual bool IsSecurityTransparent { get { throw NotImplemented.ByDesign; } }
+
+        public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
+        public ConstructorInfo TypeInitializer => GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, Type.EmptyTypes, null);
+
+        public ConstructorInfo GetConstructor(Type[] types) => GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
+        public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers);
+        public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+        {
+            if (types == null)
+                throw new ArgumentNullException(nameof(types));
+            for (int i = 0; i < types.Length; i++)
+            {
+                if (types[i] == null)
+                    throw new ArgumentNullException(nameof(types));
+            }
+            return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
+        }
+        protected abstract ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
+
+        public ConstructorInfo[] GetConstructors() => GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+        public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
+
+        public EventInfo GetEvent(string name) => GetEvent(name, Type.DefaultLookup);
+        public abstract EventInfo GetEvent(string name, BindingFlags bindingAttr);
+
+        public virtual EventInfo[] GetEvents() => GetEvents(Type.DefaultLookup);
+        public abstract EventInfo[] GetEvents(BindingFlags bindingAttr);
+
+        public FieldInfo GetField(string name) => GetField(name, Type.DefaultLookup);
+        public abstract FieldInfo GetField(string name, BindingFlags bindingAttr);
+
+        public FieldInfo[] GetFields() => GetFields(Type.DefaultLookup);
+        public abstract FieldInfo[] GetFields(BindingFlags bindingAttr);
+
+        public MemberInfo[] GetMember(string name) => GetMember(name, Type.DefaultLookup);
+        public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr) => GetMember(name, MemberTypes.All, bindingAttr);
+        public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+        public MemberInfo[] GetMembers() => GetMembers(Type.DefaultLookup);
+        public abstract MemberInfo[] GetMembers(BindingFlags bindingAttr);
+
+        public MethodInfo GetMethod(string name) => GetMethod(name, Type.DefaultLookup);
+        public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
+        }
+
+        public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, types, null);
+        public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, Type.DefaultLookup, null, types, modifiers);
+        public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
+        public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            if (types == null)
+                throw new ArgumentNullException(nameof(types));
+            for (int i = 0; i < types.Length; i++)
+            {
+                if (types[i] == null)
+                    throw new ArgumentNullException(nameof(types));
+            }
+            return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
+        }
+
+        protected abstract MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
+
+        public MethodInfo[] GetMethods() => GetMethods(Type.DefaultLookup);
+        public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr);
+
+        public Type GetNestedType(string name) => GetNestedType(name, Type.DefaultLookup);
+        public abstract Type GetNestedType(string name, BindingFlags bindingAttr);
+
+        public Type[] GetNestedTypes() => GetNestedTypes(Type.DefaultLookup);
+        public abstract Type[] GetNestedTypes(BindingFlags bindingAttr);
+
+        public PropertyInfo GetProperty(string name) => GetProperty(name, Type.DefaultLookup);
+        public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            return GetPropertyImpl(name, bindingAttr, null, null, null, null);
+        }
+
+        public PropertyInfo GetProperty(string name, Type returnType)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            if (returnType == null)
+                throw new ArgumentNullException(nameof(returnType));
+            return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, null, null);
+        }
+
+        public PropertyInfo GetProperty(string name, Type[] types) => GetProperty(name, null, types);
+        public PropertyInfo GetProperty(string name, Type returnType, Type[] types) => GetProperty(name, returnType, types, null);
+        public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) => GetProperty(name, Type.DefaultLookup, null, returnType, types, modifiers);
+        public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
+        {
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+            if (types == null)
+                throw new ArgumentNullException(nameof(types));
+            return GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers);
+        }
+
+        protected abstract PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
+
+        public PropertyInfo[] GetProperties() => GetProperties(Type.DefaultLookup);
+        public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);
+
+        public virtual MemberInfo[] GetDefaultMembers() { throw NotImplemented.ByDesign; }
+
+        public virtual RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } }
+        public static RuntimeTypeHandle GetTypeHandle(object o)
+        {
+            if (o == null)
+                throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
+            Type type = o.GetType();
+            return type.TypeHandle;
+        }
+
+        public static Type[] GetTypeArray(object[] args)
+        {
+            if (args == null)
+                throw new ArgumentNullException(nameof(args));
+
+            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;
+        }
+
+        public static TypeCode GetTypeCode(Type type)
+        {
+            if (type == null)
+                return TypeCode.Empty;
+            return type.GetTypeCodeImpl();
+        }
+        protected virtual TypeCode GetTypeCodeImpl()
+        {
+            if (this != UnderlyingSystemType && UnderlyingSystemType != null)
+                return Type.GetTypeCode(UnderlyingSystemType);
+
+            return TypeCode.Object;
+        }
+
+        public abstract Guid GUID { get; }
+
+        public static Type GetTypeFromCLSID(Guid clsid) => GetTypeFromCLSID(clsid, null, throwOnError: false);
+        public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError) => GetTypeFromCLSID(clsid, null, throwOnError: throwOnError);
+        public static Type GetTypeFromCLSID(Guid clsid, string server) => GetTypeFromCLSID(clsid, server, throwOnError: false);
+
+        public static Type GetTypeFromProgID(string progID) => GetTypeFromProgID(progID, null, throwOnError: false);
+        public static Type GetTypeFromProgID(string progID, bool throwOnError) => GetTypeFromProgID(progID, null, throwOnError: throwOnError);
+        public static Type GetTypeFromProgID(string progID, string server) => GetTypeFromProgID(progID, server, throwOnError: false);
+
+        public abstract Type BaseType { get; }
+
+        [DebuggerHidden]
+        [DebuggerStepThrough]
+        public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) => InvokeMember(name, invokeAttr, binder, target, args, null, null, null);
+
+        [DebuggerHidden]
+        [DebuggerStepThrough]
+        public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture) => InvokeMember(name, invokeAttr, binder, target, args, null, culture, null);
+        public abstract object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
+
+        public Type GetInterface(string name) => GetInterface(name, ignoreCase: false);
+        public abstract Type GetInterface(string name, bool ignoreCase);
+        public abstract Type[] GetInterfaces();
+
+        public virtual InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+        public virtual bool IsInstanceOfType(object o) => o == null ? false : IsAssignableFrom(o.GetType());
+        public virtual bool IsEquivalentTo(Type other) => this == other;
+
+        public virtual Type GetEnumUnderlyingType()
+        {
+            if (!IsEnum)
+                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+            FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+            if (fields == null || fields.Length != 1)
+                throw new ArgumentException(SR.Argument_InvalidEnum, "enumType");
+
+            return fields[0].FieldType;
+        }
+        public virtual Array GetEnumValues()
+        {
+            if (!IsEnum)
+                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+            // 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.
+            throw NotImplemented.ByDesign;
+        }
+
+        public virtual Type MakeArrayType() { throw new NotSupportedException(); }
+        public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
+        public virtual Type MakeByRefType() { throw new NotSupportedException(); }
+        public virtual Type MakeGenericType(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+        public virtual Type MakePointerType() { throw new NotSupportedException(); }
+
+        public override string ToString() => "Type: " + Name;  // Why do we add the "Type: " prefix?
+
+        public override bool Equals(object o) => o == null ? false : Equals(o as Type);
+        public override int GetHashCode()
+        {
+            Type systemType = UnderlyingSystemType;
+            if (!object.ReferenceEquals(systemType, this))
+                return systemType.GetHashCode();
+            return base.GetHashCode();
+        }
+        public virtual bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType);
+
+        public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
+
+        public static readonly char Delimiter = '.';
+        public static readonly Type[] EmptyTypes = Array.Empty<Type>();
+        public static readonly object Missing = System.Reflection.Missing.Value;
+
+        public static readonly MemberFilter FilterAttribute = FilterAttributeImpl;
+        public static readonly MemberFilter FilterName = FilterNameImpl;
+        public static readonly MemberFilter FilterNameIgnoreCase = FilterNameIgnoreCaseImpl;
+
+        private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+    }
+}