// // System.Type.cs // // Authors: // Miguel de Icaza (miguel@ximian.com) // Marek Safar (marek.safar@gmail.com) // // (C) Ximian, Inc. http://www.ximian.com // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.Diagnostics; using System.Reflection; #if !FULL_AOT_RUNTIME using System.Reflection.Emit; #endif using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; using System.Globalization; namespace System { [Serializable] [ClassInterface (ClassInterfaceType.None)] [ComVisible (true)] [ComDefaultInterface (typeof (_Type))] [StructLayout (LayoutKind.Sequential)] #if MOBILE public abstract class Type : MemberInfo, IReflect { #else public abstract class Type : MemberInfo, IReflect, _Type { #endif internal RuntimeTypeHandle _impl; public static readonly char Delimiter = '.'; public static readonly Type[] EmptyTypes = {}; public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl); public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl); public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl); public static readonly object Missing = System.Reflection.Missing.Value; internal const BindingFlags DefaultBindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; /* implementation of the delegates for MemberFilter */ static bool FilterName_impl (MemberInfo m, object filterCriteria) { string name = (string) filterCriteria; if (name == null || name.Length == 0 ) return false; // because m.Name cannot be null or empty if (name [name.Length - 1] == '*') return m.Name.StartsWithOrdinalUnchecked (name.Substring (0, name.Length - 1)); return m.Name == name; } static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria) { string name = (string) filterCriteria; if (name == null || name.Length == 0 ) return false; // because m.Name cannot be null or empty if (name [name.Length - 1] == '*') return m.Name.StartsWithOrdinalCaseInsensitiveUnchecked (name.Substring (0, name.Length - 1)); return string.CompareOrdinalCaseInsensitiveUnchecked (m.Name, name) == 0; } static bool FilterAttribute_impl (MemberInfo m, object filterCriteria) { if (!(filterCriteria is int)) throw new InvalidFilterCriteriaException ("Int32 value is expected for filter criteria"); int flags = (int) filterCriteria; if (m is MethodInfo) return ((int)((MethodInfo)m).Attributes & flags) != 0; if (m is FieldInfo) return ((int)((FieldInfo)m).Attributes & flags) != 0; if (m is PropertyInfo) return ((int)((PropertyInfo)m).Attributes & flags) != 0; if (m is EventInfo) return ((int)((EventInfo)m).Attributes & flags) != 0; return false; } protected Type () { } /// /// The assembly where the type is defined. /// public abstract Assembly Assembly { get; } /// /// Gets the fully qualified name for the type including the /// assembly name where the type is defined. /// public abstract string AssemblyQualifiedName { get; } /// /// Returns the Attributes associated with the type. /// public TypeAttributes Attributes { get { return GetAttributeFlagsImpl (); } } /// /// Returns the basetype for this type /// public abstract Type BaseType { get; } /// /// Returns the class that declares the member. /// public override Type DeclaringType { get { return null; } } /// /// /// public static Binder DefaultBinder { get { return Binder.DefaultBinder; } } /// /// The full name of the type including its namespace /// public abstract string FullName { get; } public abstract Guid GUID { get; } public bool HasElementType { get { return HasElementTypeImpl (); } } public bool IsAbstract { get { return (Attributes & TypeAttributes.Abstract) != 0; } } public bool IsAnsiClass { get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; } } public bool IsArray { get { return IsArrayImpl (); } } public bool IsAutoClass { get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; } } public bool IsAutoLayout { get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; } } public bool IsByRef { get { return IsByRefImpl (); } } public bool IsClass { get { if (IsInterface) return false; return !IsValueType; } } public bool IsCOMObject { get { return IsCOMObjectImpl (); } } #if NET_4_5 public virtual bool IsConstructedGenericType { get { throw new NotImplementedException (); } } #endif public bool IsContextful { get { return IsContextfulImpl (); } } public #if NET_4_0 virtual #endif bool IsEnum { get { return IsSubclassOf (typeof (Enum)); } } public bool IsExplicitLayout { get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; } } public bool IsImport { get { return (Attributes & TypeAttributes.Import) != 0; } } public bool IsInterface { get { return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface; } } public bool IsLayoutSequential { get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; } } public bool IsMarshalByRef { get { return IsMarshalByRefImpl (); } } public bool IsNestedAssembly { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; } } public bool IsNestedFamANDAssem { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; } } public bool IsNestedFamily { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; } } public bool IsNestedFamORAssem { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; } } public bool IsNestedPrivate { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; } } public bool IsNestedPublic { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; } } public bool IsNotPublic { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; } } public bool IsPointer { get { return IsPointerImpl (); } } public bool IsPrimitive { get { return IsPrimitiveImpl (); } } public bool IsPublic { get { return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; } } public bool IsSealed { get { return (Attributes & TypeAttributes.Sealed) != 0; } } public #if NET_4_0 virtual #endif bool IsSerializable { get { if ((Attributes & TypeAttributes.Serializable) != 0) return true; // Enums and delegates are always serializable Type type = UnderlyingSystemType; if (type == null) return false; // Fast check for system types if (type.IsSystemType) return type_is_subtype_of (type, typeof (Enum), false) || type_is_subtype_of (type, typeof (Delegate), false); // User defined types depend on this behavior do { if ((type == typeof (Enum)) || (type == typeof (Delegate))) return true; type = type.BaseType; } while (type != null); return false; } } public bool IsSpecialName { get { return (Attributes & TypeAttributes.SpecialName) != 0; } } public bool IsUnicodeClass { get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; } } public bool IsValueType { get { return IsValueTypeImpl (); } } public override MemberTypes MemberType { get { return MemberTypes.TypeInfo; } } public abstract override Module Module { get; } public abstract string Namespace {get;} public override Type ReflectedType { get { return null; } } public virtual RuntimeTypeHandle TypeHandle { get { throw new ArgumentException ("Derived class must provide implementation."); } } [ComVisible (true)] public ConstructorInfo TypeInitializer { get { return GetConstructorImpl ( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, CallingConventions.Any, EmptyTypes, null); } } /* * This has NOTHING to do with getting the base type of an enum. Use * Enum.GetUnderlyingType () for that. */ public abstract Type UnderlyingSystemType {get;} public override bool Equals (object o) { #if NET_4_0 return Equals (o as Type); #else if (o == this) return true; Type me = UnderlyingSystemType; if (me == null) return false; return me.EqualsInternal (o as Type); #endif } #if NET_4_0 public virtual bool Equals (Type o) { if ((object)o == (object)this) return true; if ((object)o == null) return false; Type me = UnderlyingSystemType; if ((object)me == null) return false; o = o.UnderlyingSystemType; if ((object)o == null) return false; if ((object)o == (object)this) return true; return me.EqualsInternal (o); } #else public bool Equals (Type o) { if (o == this) return true; if (o == null) return false; Type me = UnderlyingSystemType; if (me == null) return false; return me.EqualsInternal (o.UnderlyingSystemType); } #endif #if NET_4_0 [MonoTODO ("Implement it properly once 4.0 impl details are known.")] public static bool operator == (Type left, Type right) { return Object.ReferenceEquals (left, right); } [MonoTODO ("Implement it properly once 4.0 impl details are known.")] public static bool operator != (Type left, Type right) { return !Object.ReferenceEquals (left, right); } [MonoInternalNote ("Reimplement this in MonoType for bonus speed")] public virtual Type GetEnumUnderlyingType () { if (!IsEnum) throw new ArgumentException ("Type is not an enumeration", "enumType"); var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (fields == null || fields.Length != 1) throw new ArgumentException ("An enum must have exactly one instance field", "enumType"); return fields [0].FieldType; } [MonoInternalNote ("Reimplement this in MonoType for bonus speed")] public virtual string[] GetEnumNames () { if (!IsEnum) throw new ArgumentException ("Type is not an enumeration", "enumType"); var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); string [] names = new string [fields.Length]; if (0 != names.Length) { for (int i = 0; i < fields.Length; ++i) names [i] = fields [i].Name; var et = GetEnumUnderlyingType (); var values = Array.CreateInstance (et, names.Length); for (int i = 0; i < fields.Length; ++i) values.SetValue (fields [i].GetValue (null), i); MonoEnumInfo.SortEnums (et, values, names); } return names; } static NotImplementedException CreateNIE () { return new NotImplementedException (); } public virtual Array GetEnumValues () { if (!IsEnum) throw new ArgumentException ("Type is not an enumeration", "enumType"); throw CreateNIE (); } bool IsValidEnumType (Type type) { return (type.IsPrimitive && type != typeof (bool) && type != typeof (double) && type != typeof (float)) || type.IsEnum; } [MonoInternalNote ("Reimplement this in MonoType for bonus speed")] public virtual string GetEnumName (object value) { if (value == null) throw new ArgumentException ("Value is null", "value"); if (!IsValidEnumType (value.GetType ())) throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value"); if (!IsEnum) throw new ArgumentException ("Type is not an enumeration", "enumType"); object obj = null; var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); for (int i = 0; i < fields.Length; ++i) { var fv = fields [i].GetValue (null); if (obj == null) { try { //XXX we can't use 'this' as argument as it might be an UserType obj = Enum.ToObject (fv.GetType (), value); } catch (OverflowException) { return null; } catch (InvalidCastException) { throw new ArgumentException ("Value is not valid", "value"); } } if (fv.Equals (obj)) return fields [i].Name; } return null; } [MonoInternalNote ("Reimplement this in MonoType for bonus speed")] public virtual bool IsEnumDefined (object value) { if (value == null) throw new ArgumentException ("Value is null", "value"); if (!IsEnum) throw new ArgumentException ("Type is not an enumeration", "enumType"); Type vt = value.GetType (); if (!IsValidEnumType (vt) && vt != typeof (string)) throw new InvalidOperationException ("Value is not the enum or a valid enum underlying type"); var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (value is string) { for (int i = 0; i < fields.Length; ++i) { if (fields [i].Name.Equals (value)) return true; } } else { if (vt != this && vt != GetEnumUnderlyingType ()) throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value"); object obj = null; for (int i = 0; i < fields.Length; ++i) { var fv = fields [i].GetValue (null); if (obj == null) { try { //XXX we can't use 'this' as argument as it might be an UserType obj = Enum.ToObject (fv.GetType (), value); } catch (OverflowException) { return false; } catch (InvalidCastException) { throw new ArgumentException ("Value is not valid", "value"); } } if (fv.Equals (obj)) return true; } } return false; } public static Type GetType (string typeName, Func assemblyResolver, Func typeResolver) { return GetType (typeName, assemblyResolver, typeResolver, false, false); } public static Type GetType (string typeName, Func assemblyResolver, Func typeResolver, bool throwOnError) { return GetType (typeName, assemblyResolver, typeResolver, throwOnError, false); } public static Type GetType (string typeName, Func assemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase) { TypeSpec spec = TypeSpec.Parse (typeName); return spec.Resolve (assemblyResolver, typeResolver, throwOnError, ignoreCase); } public virtual bool IsSecurityTransparent { get { throw CreateNIE (); } } public virtual bool IsSecurityCritical { get { throw CreateNIE (); } } public virtual bool IsSecuritySafeCritical { get { throw CreateNIE (); } } #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern bool EqualsInternal (Type type); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern Type internal_from_handle (IntPtr handle); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase); public static Type GetType(string typeName) { if (typeName == null) throw new ArgumentNullException ("TypeName"); return internal_from_name (typeName, false, false); } public static Type GetType(string typeName, bool throwOnError) { if (typeName == null) throw new ArgumentNullException ("TypeName"); Type type = internal_from_name (typeName, throwOnError, false); if (throwOnError && type == null) throw new TypeLoadException ("Error loading '" + typeName + "'"); return type; } public static Type GetType(string typeName, bool throwOnError, bool ignoreCase) { if (typeName == null) throw new ArgumentNullException ("TypeName"); Type t = internal_from_name (typeName, throwOnError, ignoreCase); if (throwOnError && t == null) throw new TypeLoadException ("Error loading '" + typeName + "'"); return t; } public static Type[] GetTypeArray (object[] args) { if (args == null) throw new ArgumentNullException ("args"); Type[] ret; ret = new Type [args.Length]; for (int i = 0; i < args.Length; ++i) ret [i] = args[i].GetType (); return ret; } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static TypeCode GetTypeCodeInternal (Type type); #if NET_4_0 protected virtual #endif TypeCode GetTypeCodeImpl () { Type type = this; if (type is MonoType) return GetTypeCodeInternal (type); #if !FULL_AOT_RUNTIME if (type is TypeBuilder) return ((TypeBuilder)type).GetTypeCodeInternal (); #endif type = type.UnderlyingSystemType; if (!type.IsSystemType) return TypeCode.Object; else return GetTypeCodeInternal (type); } public static TypeCode GetTypeCode (Type type) { if (type == null) /* MS.NET returns this */ return TypeCode.Empty; return type.GetTypeCodeImpl (); } #if !FULL_AOT_RUNTIME private static Dictionary clsid_types; private static AssemblyBuilder clsid_assemblybuilder; #endif [MonoTODO("COM servers only work on Windows")] public static Type GetTypeFromCLSID (Guid clsid) { return GetTypeFromCLSID (clsid, null, true); } [MonoTODO("COM servers only work on Windows")] public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError) { return GetTypeFromCLSID (clsid, null, throwOnError); } [MonoTODO("COM servers only work on Windows")] public static Type GetTypeFromCLSID (Guid clsid, string server) { return GetTypeFromCLSID (clsid, server, true); } [MonoTODO("COM servers only work on Windows")] public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError) { #if !FULL_AOT_RUNTIME Type result; if (clsid_types == null) { Dictionary new_clsid_types = new Dictionary (); Interlocked.CompareExchange>( ref clsid_types, new_clsid_types, null); } lock (clsid_types) { if (clsid_types.TryGetValue(clsid, out result)) return result; if (clsid_assemblybuilder == null) { AssemblyName assemblyname = new AssemblyName (); assemblyname.Name = "GetTypeFromCLSIDDummyAssembly"; clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly ( assemblyname, AssemblyBuilderAccess.Run); } ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule ( clsid.ToString ()); TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject", TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject)); Type[] guidattrtypes = new Type[] { typeof(string) }; CustomAttributeBuilder customattr = new CustomAttributeBuilder ( typeof(GuidAttribute).GetConstructor (guidattrtypes), new object[] { clsid.ToString () }); typebuilder.SetCustomAttribute (customattr); customattr = new CustomAttributeBuilder ( typeof(ComImportAttribute).GetConstructor (EmptyTypes), new object[0] {}); typebuilder.SetCustomAttribute (customattr); result = typebuilder.CreateType (); clsid_types.Add(clsid, result); return result; } #else throw new NotImplementedException (); #endif } public static Type GetTypeFromHandle (RuntimeTypeHandle handle) { if (handle.Value == IntPtr.Zero) // This is not consistent with the other GetXXXFromHandle methods, but // MS.NET seems to do this return null; return internal_from_handle (handle.Value); } [MonoTODO("Mono does not support COM")] public static Type GetTypeFromProgID (string progID) { throw new NotImplementedException (); } [MonoTODO("Mono does not support COM")] public static Type GetTypeFromProgID (string progID, bool throwOnError) { throw new NotImplementedException (); } [MonoTODO("Mono does not support COM")] public static Type GetTypeFromProgID (string progID, string server) { throw new NotImplementedException (); } [MonoTODO("Mono does not support COM")] public static Type GetTypeFromProgID (string progID, string server, bool throwOnError) { throw new NotImplementedException (); } public static RuntimeTypeHandle GetTypeHandle (object o) { if (o == null) throw new ArgumentNullException (); return o.GetType().TypeHandle; } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool type_is_assignable_from (Type a, Type b); public new Type GetType () { return base.GetType (); } [ComVisible (true)] public virtual bool IsSubclassOf (Type c) { if (c == null || c == this) return false; // Fast check for system types if (IsSystemType) return c.IsSystemType && type_is_subtype_of (this, c, false); // User defined types depend on this behavior for (Type type = BaseType; type != null; type = type.BaseType) if (type == c) return true; return false; } public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria) { if (filter == null) throw new ArgumentNullException ("filter"); var ifaces = new List (); foreach (Type iface in GetInterfaces ()) { if (filter (iface, filterCriteria)) ifaces.Add (iface); } return ifaces.ToArray (); } public Type GetInterface (string name) { return GetInterface (name, false); } public abstract Type GetInterface (string name, bool ignoreCase); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods); [ComVisible (true)] public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); if (interfaceType == null) throw new ArgumentNullException ("interfaceType"); if (!interfaceType.IsSystemType) throw new ArgumentException ("interfaceType", "Type is an user type"); InterfaceMapping res; if (!interfaceType.IsInterface) throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType"); if (IsInterface) throw new ArgumentException ("'this' type cannot be an interface itself"); res.TargetType = this; res.InterfaceType = interfaceType; GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods); if (res.TargetMethods == null) throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType"); return res; } public abstract Type[] GetInterfaces (); public virtual bool IsAssignableFrom (Type c) { if (c == null) return false; if (Equals (c)) return true; #if !FULL_AOT_RUNTIME if (c is TypeBuilder) return ((TypeBuilder)c).IsAssignableTo (this); #endif /* Handle user defined type classes */ if (!IsSystemType) { Type systemType = UnderlyingSystemType; if (!systemType.IsSystemType) return false; Type other = c.UnderlyingSystemType; if (!other.IsSystemType) return false; return systemType.IsAssignableFrom (other); } if (!c.IsSystemType) { Type underlyingType = c.UnderlyingSystemType; if (!underlyingType.IsSystemType) return false; return IsAssignableFrom (underlyingType); } return type_is_assignable_from (this, c); } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern static bool IsInstanceOfType (Type type, object o); public virtual bool IsInstanceOfType (object o) { Type type = UnderlyingSystemType; if (!type.IsSystemType) return false; return IsInstanceOfType (type, o); } public virtual int GetArrayRank () { throw new NotSupportedException (); // according to MSDN } public abstract Type GetElementType (); public EventInfo GetEvent (string name) { return GetEvent (name, DefaultBindingFlags); } public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr); public virtual EventInfo[] GetEvents () { return GetEvents (DefaultBindingFlags); } public abstract EventInfo[] GetEvents (BindingFlags bindingAttr); public FieldInfo GetField( string name) { return GetField (name, DefaultBindingFlags); } public abstract FieldInfo GetField( string name, BindingFlags bindingAttr); public FieldInfo[] GetFields () { return GetFields (DefaultBindingFlags); } public abstract FieldInfo[] GetFields (BindingFlags bindingAttr); public override int GetHashCode() { Type t = UnderlyingSystemType; if (t != null && t != this) return t.GetHashCode (); return (int)_impl.Value; } public MemberInfo[] GetMember (string name) { return GetMember (name, MemberTypes.All, DefaultBindingFlags); } public virtual MemberInfo[] GetMember (string name, BindingFlags bindingAttr) { return GetMember (name, MemberTypes.All, bindingAttr); } public virtual MemberInfo[] GetMember (string name, MemberTypes type, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException ("name"); if ((bindingAttr & BindingFlags.IgnoreCase) != 0) return FindMembers (type, bindingAttr, FilterNameIgnoreCase, name); else return FindMembers (type, bindingAttr, FilterName, name); } public MemberInfo[] GetMembers () { return GetMembers (DefaultBindingFlags); } public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr); public MethodInfo GetMethod (string name) { if (name == null) throw new ArgumentNullException ("name"); return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null); } public MethodInfo GetMethod (string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException ("name"); return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null); } public MethodInfo GetMethod (string name, Type[] types) { return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null); } public MethodInfo GetMethod (string name, Type[] types, ParameterModifier[] modifiers) { return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, modifiers); } public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return 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 ("name"); if (types == null) throw new ArgumentNullException ("types"); for (int i = 0; i < types.Length; i++) if (types[i] == null) throw new ArgumentNullException ("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); internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers); } internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated) { throw new System.InvalidOperationException ("can only be called in generic type"); } internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated) { throw new System.InvalidOperationException ("can only be called in generic type"); } internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated) { throw new System.InvalidOperationException ("can only be called in generic type"); } public MethodInfo[] GetMethods () { return GetMethods (DefaultBindingFlags); } public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr); public Type GetNestedType (string name) { return GetNestedType (name, DefaultBindingFlags); } public abstract Type GetNestedType (string name, BindingFlags bindingAttr); public Type[] GetNestedTypes () { return GetNestedTypes (DefaultBindingFlags); } public abstract Type[] GetNestedTypes (BindingFlags bindingAttr); public PropertyInfo[] GetProperties () { return GetProperties (DefaultBindingFlags); } public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr); public PropertyInfo GetProperty (string name) { if (name == null) throw new ArgumentNullException ("name"); return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null); } public PropertyInfo GetProperty (string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException ("name"); return GetPropertyImpl (name, bindingAttr, null, null, null, null); } public PropertyInfo GetProperty (string name, Type returnType) { if (name == null) throw new ArgumentNullException ("name"); return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null); } public PropertyInfo GetProperty (string name, Type[] types) { return GetProperty (name, DefaultBindingFlags, null, null, types, null); } public PropertyInfo GetProperty (string name, Type returnType, Type[] types) { return GetProperty (name, DefaultBindingFlags, null, returnType, types, null); } public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers) { return GetProperty (name, DefaultBindingFlags, 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 ("name"); if (types == null) throw new ArgumentNullException ("types"); foreach (Type t in types) { if (t == null) throw new ArgumentNullException ("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); internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers); } protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); protected abstract TypeAttributes GetAttributeFlagsImpl (); protected abstract bool HasElementTypeImpl (); protected abstract bool IsArrayImpl (); protected abstract bool IsByRefImpl (); protected abstract bool IsCOMObjectImpl (); protected abstract bool IsPointerImpl (); protected abstract bool IsPrimitiveImpl (); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool IsArrayImpl (Type type); protected virtual bool IsValueTypeImpl () { if (this == typeof (ValueType) || this == typeof (Enum)) return false; return IsSubclassOf (typeof (ValueType)); } protected virtual bool IsContextfulImpl () { return typeof (ContextBoundObject).IsAssignableFrom (this); } protected virtual bool IsMarshalByRefImpl () { return typeof (MarshalByRefObject).IsAssignableFrom (this); } [ComVisible (true)] public ConstructorInfo GetConstructor (Type[] types) { return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null); } [ComVisible (true)] public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { return GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers); } [ComVisible (true)] public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { if (types == null) throw new ArgumentNullException ("types"); foreach (Type t in types) { if (t == null) throw new ArgumentNullException ("types"); } return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers); } [ComVisible (true)] public ConstructorInfo[] GetConstructors () { return GetConstructors (BindingFlags.Public | BindingFlags.Instance); } [ComVisible (true)] public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr); public virtual MemberInfo[] GetDefaultMembers () { object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true); if (att.Length == 0) return EmptyArray.Value; MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName); return (member != null) ? member : EmptyArray.Value; } public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria) { MemberInfo[] result; ArrayList l = new ArrayList (); // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}", // this.FullName, this.GetType().FullName, this.obj_address()); if ((memberType & MemberTypes.Method) != 0) { MethodInfo[] c = GetMethods (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) l.Add (m); } } else { l.AddRange (c); } } if ((memberType & MemberTypes.Constructor) != 0) { ConstructorInfo[] c = GetConstructors (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) l.Add (m); } } else { l.AddRange (c); } } if ((memberType & MemberTypes.Property) != 0) { PropertyInfo[] c = GetProperties (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) l.Add (m); } } else { l.AddRange (c); } } if ((memberType & MemberTypes.Event) != 0) { EventInfo[] c = GetEvents (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) l.Add (m); } } else { l.AddRange (c); } } if ((memberType & MemberTypes.Field) != 0) { FieldInfo[] c = GetFields (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) l.Add (m); } } else { l.AddRange (c); } } if ((memberType & MemberTypes.NestedType) != 0) { Type[] c = GetNestedTypes (bindingAttr); if (filter != null) { foreach (MemberInfo m in c) { if (filter (m, filterCriteria)) { l.Add (m); } } } else { l.AddRange (c); } } switch (memberType) { case MemberTypes.Constructor : result = new ConstructorInfo [l.Count]; break; case MemberTypes.Event : result = new EventInfo [l.Count]; break; case MemberTypes.Field : result = new FieldInfo [l.Count]; break; case MemberTypes.Method : result = new MethodInfo [l.Count]; break; case MemberTypes.NestedType : case MemberTypes.TypeInfo : result = new Type [l.Count]; break; case MemberTypes.Property : result = new PropertyInfo [l.Count]; break; default : result = new MemberInfo [l.Count]; break; } l.CopyTo (result); return result; } [DebuggerHidden] [DebuggerStepThrough] public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) { return 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) { return 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 override string ToString() { return FullName; } internal static bool ShouldPrintFullName (Type type) { return type.IsGenericType || (type.IsClass && (!type.IsPointer || (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested))); } internal virtual Type InternalResolve () { return UnderlyingSystemType; } internal bool IsSystemType { get { return _impl.Value != IntPtr.Zero; } } #if NET_4_5 public virtual Type[] GenericTypeArguments { get { return IsGenericType ? GetGenericArguments () : EmptyTypes; } } #endif public virtual Type[] GetGenericArguments () { throw new NotSupportedException (); } public virtual bool ContainsGenericParameters { get { return false; } } public virtual extern bool IsGenericTypeDefinition { [MethodImplAttribute(MethodImplOptions.InternalCall)] get; } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern Type GetGenericTypeDefinition_impl (); public virtual Type GetGenericTypeDefinition () { throw new NotSupportedException ("Derived classes must provide an implementation."); } public virtual extern bool IsGenericType { [MethodImplAttribute(MethodImplOptions.InternalCall)] get; } [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern Type MakeGenericType (Type gt, Type [] types); public virtual Type MakeGenericType (params Type[] typeArguments) { if (IsUserType) throw new NotSupportedException (); if (!IsGenericTypeDefinition) throw new InvalidOperationException ("not a generic type definition"); if (typeArguments == null) throw new ArgumentNullException ("typeArguments"); if (GetGenericArguments().Length != typeArguments.Length) throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments"); bool hasUserType = false; Type[] systemTypes = new Type[typeArguments.Length]; for (int i = 0; i < typeArguments.Length; ++i) { Type t = typeArguments [i]; if (t == null) throw new ArgumentNullException ("typeArguments"); if (!(t is MonoType)) hasUserType = true; systemTypes [i] = t; } if (hasUserType) { #if FULL_AOT_RUNTIME throw new NotSupportedException ("User types are not supported under full aot"); #else return new MonoGenericClass (this, typeArguments); #endif } Type res = MakeGenericType (this, systemTypes); if (res == null) throw new TypeLoadException (); return res; } public virtual bool IsGenericParameter { get { return false; } } public bool IsNested { get { return DeclaringType != null; } } public bool IsVisible { get { if (IsNestedPublic) return DeclaringType.IsVisible; return IsPublic; } } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern int GetGenericParameterPosition (); public virtual int GenericParameterPosition { get { int res = GetGenericParameterPosition (); if (res < 0) throw new InvalidOperationException (); return res; } } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern GenericParameterAttributes GetGenericParameterAttributes (); public virtual GenericParameterAttributes GenericParameterAttributes { get { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); if (!IsGenericParameter) throw new InvalidOperationException (); return GetGenericParameterAttributes (); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern Type[] GetGenericParameterConstraints_impl (); public virtual Type[] GetGenericParameterConstraints () { if (!IsSystemType) throw new InvalidOperationException (); if (!IsGenericParameter) throw new InvalidOperationException (); return GetGenericParameterConstraints_impl (); } public virtual MethodBase DeclaringMethod { get { return null; } } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern Type make_array_type (int rank); public virtual Type MakeArrayType () { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); return make_array_type (0); } public virtual Type MakeArrayType (int rank) { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); if (rank < 1 || rank > 255) throw new IndexOutOfRangeException (); return make_array_type (rank); } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern Type make_byref_type (); public virtual Type MakeByRefType () { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); if (IsByRef) throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type"); return make_byref_type (); } [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern Type MakePointerType (Type type); public virtual Type MakePointerType () { if (!IsSystemType) throw new NotSupportedException ("Derived classes must provide an implementation."); return MakePointerType (this); } public static Type ReflectionOnlyGetType (string typeName, bool throwIfNotFound, bool ignoreCase) { if (typeName == null) throw new ArgumentNullException ("typeName"); int idx = typeName.IndexOf (','); if (idx < 0 || idx == 0 || idx == typeName.Length - 1) throw new ArgumentException ("Assembly qualifed type name is required", "typeName"); string an = typeName.Substring (idx + 1); Assembly a; try { a = Assembly.ReflectionOnlyLoad (an); } catch { if (throwIfNotFound) throw; return null; } return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase); } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern void GetPacking (out int packing, out int size); public virtual StructLayoutAttribute StructLayoutAttribute { get { #if NET_4_0 throw new NotSupportedException (); #else return GetStructLayoutAttribute (); #endif } } internal StructLayoutAttribute GetStructLayoutAttribute () { LayoutKind kind; if (IsLayoutSequential) kind = LayoutKind.Sequential; else if (IsExplicitLayout) kind = LayoutKind.Explicit; else kind = LayoutKind.Auto; StructLayoutAttribute attr = new StructLayoutAttribute (kind); if (IsUnicodeClass) attr.CharSet = CharSet.Unicode; else if (IsAnsiClass) attr.CharSet = CharSet.Ansi; else attr.CharSet = CharSet.Auto; if (kind != LayoutKind.Auto) { int packing; GetPacking (out packing, out attr.Size); // 0 means no data provided, we end up with default value if (packing != 0) attr.Pack = packing; } return attr; } internal object[] GetPseudoCustomAttributes () { int count = 0; /* IsSerializable returns true for delegates/enums as well */ if ((Attributes & TypeAttributes.Serializable) != 0) count ++; if ((Attributes & TypeAttributes.Import) != 0) count ++; if (count == 0) return null; object[] attrs = new object [count]; count = 0; if ((Attributes & TypeAttributes.Serializable) != 0) attrs [count ++] = new SerializableAttribute (); if ((Attributes & TypeAttributes.Import) != 0) attrs [count ++] = new ComImportAttribute (); return attrs; } #if NET_4_0 public virtual bool IsEquivalentTo (Type other) { return this == other; } #endif /* * Return whenever this object is an instance of a user defined subclass * of System.Type or an instance of TypeDelegator. * A user defined type is not simply the opposite of a system type. * It's any class that's neither a SRE or runtime baked type. */ internal virtual bool IsUserType { get { return true; } } #if !MOBILE void _Type.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) { throw new NotImplementedException (); } void _Type.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) { throw new NotImplementedException (); } void _Type.GetTypeInfoCount (out uint pcTInfo) { throw new NotImplementedException (); } 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 } }