// 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.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 assemblyResolver, Func 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 assemblyResolver, Func 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 assemblyResolver, Func 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(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() >= 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() != 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() != 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() != 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() != 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(out enumNames) != null); Contract.Ensures(Contract.ValueAtReturn(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() != 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; } }