5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
9 // TODO: Mucho left to implement.
12 using System.Reflection;
13 using System.Collections;
14 using System.Runtime.InteropServices;
15 using System.Runtime.CompilerServices;
16 using System.Globalization;
21 // FIXME: Implement the various IReflect dependencies
26 [ClassInterface (ClassInterfaceType.AutoDual)]
27 public abstract class Type : MemberInfo, IReflect {
29 internal RuntimeTypeHandle _impl;
31 public static readonly char Delimiter = '.';
32 public static readonly Type[] EmptyTypes = {};
33 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
34 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
35 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
36 public static readonly object Missing;
38 protected const BindingFlags DefaultBindingFlags =
39 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
41 /* implementation of the delegates for MemberFilter */
42 static bool FilterName_impl (MemberInfo m, object filterCriteria)
44 string name = (string) filterCriteria;
45 return name.Equals (m.Name);
48 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
50 string name = (string) filterCriteria;
51 return String.Compare (name, m.Name, true, CultureInfo.InvariantCulture) == 0;
55 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
57 throw new NotImplementedException ("FilterAttribute_impl");
65 /// The assembly where the type is defined.
67 public abstract Assembly Assembly {
72 /// Gets the fully qualified name for the type including the
73 /// assembly name where the type is defined.
75 public abstract string AssemblyQualifiedName {
80 /// Returns the Attributes associated with the type.
82 public TypeAttributes Attributes {
84 return GetAttributeFlagsImpl ();
89 /// Returns the basetype for this type
91 public abstract Type BaseType {
96 /// Returns the class that declares the member.
98 public override Type DeclaringType {
107 public static Binder DefaultBinder {
109 return Binder.DefaultBinder;
114 /// The full name of the type including its namespace
116 public abstract string FullName {
120 public abstract Guid GUID {
124 public bool HasElementType {
126 return HasElementTypeImpl ();
130 public bool IsAbstract {
132 return (Attributes & TypeAttributes.Abstract) != 0;
136 public bool IsAnsiClass {
138 return (Attributes & TypeAttributes.StringFormatMask)
139 == TypeAttributes.AnsiClass;
143 public bool IsArray {
145 return IsArrayImpl ();
149 public bool IsAutoClass {
151 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
155 public bool IsAutoLayout {
157 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
161 public bool IsByRef {
163 return IsByRefImpl ();
167 public bool IsClass {
170 // This code used to probe for "this == typeof (System.Enum)", but in
171 // The .NET Framework 1.0, the above test return false
173 if (this == typeof (System.ValueType))
177 return !type_is_subtype_of (this, typeof (System.ValueType), false);
181 public bool IsCOMObject {
183 return IsCOMObjectImpl ();
187 public bool IsContextful {
189 return IsContextfulImpl ();
195 return type_is_subtype_of (this, typeof (System.Enum), false) &&
196 this != typeof (System.Enum);
200 public bool IsExplicitLayout {
202 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
206 public bool IsImport {
208 return (Attributes & TypeAttributes.Import) != 0;
212 public bool IsInterface {
214 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
218 public bool IsLayoutSequential {
220 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
224 public bool IsMarshalByRef {
226 return IsMarshalByRefImpl ();
230 public bool IsNestedAssembly {
232 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
236 public bool IsNestedFamANDAssem {
238 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
242 public bool IsNestedFamily {
244 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
248 public bool IsNestedFamORAssem {
250 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
254 public bool IsNestedPrivate {
256 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
260 public bool IsNestedPublic {
262 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
266 public bool IsNotPublic {
268 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
272 public bool IsPointer {
274 return IsPointerImpl ();
278 public bool IsPrimitive {
280 return IsPrimitiveImpl ();
284 public bool IsPublic {
286 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
290 public bool IsSealed {
292 return (Attributes & TypeAttributes.Sealed) != 0;
296 public bool IsSerializable {
298 // Enums and delegates are always serializable
299 return (Attributes & TypeAttributes.Serializable) != 0 || IsEnum ||
300 type_is_subtype_of (this, typeof (System.Delegate), false);
304 public bool IsSpecialName {
306 return (Attributes & TypeAttributes.SpecialName) != 0;
310 public bool IsUnicodeClass {
312 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
316 public bool IsValueType {
318 return IsValueTypeImpl ();
322 public override MemberTypes MemberType {
323 get {return MemberTypes.TypeInfo;}
326 public abstract Module Module {get;}
328 public abstract string Namespace {get;}
330 public override Type ReflectedType {
336 public abstract RuntimeTypeHandle TypeHandle {get;}
338 public ConstructorInfo TypeInitializer {
340 return GetConstructorImpl (
341 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
343 CallingConventions.Any,
349 public abstract Type UnderlyingSystemType {get;}
351 public override bool Equals (object o)
356 // TODO: return UnderlyingSystemType == o.UnderlyingSystemType;
357 Type cmp = o as Type;
363 [MethodImplAttribute(MethodImplOptions.InternalCall)]
364 public extern bool Equals (Type type);
366 [MethodImplAttribute(MethodImplOptions.InternalCall)]
367 private static extern Type internal_from_handle (IntPtr handle);
369 [MethodImplAttribute(MethodImplOptions.InternalCall)]
370 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
372 public static Type GetType(string typeName)
374 if (typeName == null)
375 throw new ArgumentNullException ("typeName");
377 return internal_from_name (typeName, false, false);
380 public static Type GetType(string typeName, bool throwOnError)
382 if (typeName == null)
383 throw new ArgumentNullException ("typeName");
385 Type type = internal_from_name (typeName, throwOnError, false);
386 if (throwOnError && type == null)
387 throw new TypeLoadException ("Error loading '" + typeName + "'");
392 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
394 if (typeName == null)
395 throw new ArgumentNullException ("typeName");
397 Type t = internal_from_name (typeName, throwOnError, ignoreCase);
398 if (throwOnError && t == null)
399 throw new TypeLoadException ("Error loading '" + typeName + "'");
404 public static Type[] GetTypeArray (object[] args) {
406 throw new ArgumentNullException ("args");
409 ret = new Type [args.Length];
410 for (int i = 0; i < args.Length; ++i)
411 ret [i] = args[i].GetType ();
415 [MethodImplAttribute(MethodImplOptions.InternalCall)]
416 public extern static TypeCode GetTypeCode (Type type);
419 public static Type GetTypeFromCLSID (Guid clsid)
421 throw new NotImplementedException ();
425 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
427 throw new NotImplementedException ();
431 public static Type GetTypeFromCLSID (Guid clsid, string server)
433 throw new NotImplementedException ();
437 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
439 throw new NotImplementedException ();
442 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
444 return internal_from_handle (handle.Value);
448 public static Type GetTypeFromProgID (string progID)
450 throw new NotImplementedException ();
454 public static Type GetTypeFromProgID (string progID, bool throwOnError)
456 throw new NotImplementedException ();
460 public static Type GetTypeFromProgID (string progID, string server)
462 throw new NotImplementedException ();
466 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
468 throw new NotImplementedException ();
471 public static RuntimeTypeHandle GetTypeHandle (object o)
473 return o.GetType().TypeHandle;
476 [MethodImplAttribute(MethodImplOptions.InternalCall)]
477 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
479 [MethodImplAttribute(MethodImplOptions.InternalCall)]
480 internal static extern bool type_is_assignable_from (Type a, Type b);
482 public virtual bool IsSubclassOf (Type c)
487 return (this != c) && type_is_subtype_of (this, c, false);
490 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
493 throw new ArgumentNullException ("filter");
495 ArrayList ifaces = new ArrayList ();
496 foreach (Type iface in GetInterfaces ()) {
497 if (filter (iface, filterCriteria))
501 return (Type []) ifaces.ToArray (typeof (Type));
504 public Type GetInterface (string name) {
505 return GetInterface (name, false);
508 public abstract Type GetInterface (string name, bool ignoreCase);
510 [MethodImplAttribute(MethodImplOptions.InternalCall)]
511 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
513 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
514 InterfaceMapping res;
515 if (interfaceType == null)
516 throw new ArgumentNullException ("interfaceType");
517 if (!interfaceType.IsInterface)
518 throw new ArgumentException ("type argument must be an interface", "interfaceType");
519 res.TargetType = this;
520 res.InterfaceType = interfaceType;
521 GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
522 if (res.TargetMethods == null)
523 throw new ArgumentException ("interface not found", "interfaceType");
528 public abstract Type[] GetInterfaces ();
530 public virtual bool IsAssignableFrom (Type c)
538 return type_is_assignable_from (this, c);
541 public virtual bool IsInstanceOfType (object o) {
543 return IsAssignableFrom (o.GetType ());
548 public virtual int GetArrayRank ()
550 throw new NotSupportedException (); // according to MSDN
553 public abstract Type GetElementType ();
555 public EventInfo GetEvent (string name)
557 return GetEvent (name, DefaultBindingFlags);
560 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
562 public virtual EventInfo[] GetEvents ()
564 return GetEvents (DefaultBindingFlags);
567 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
569 public FieldInfo GetField( string name)
571 return GetField (name, DefaultBindingFlags);
574 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
576 public FieldInfo[] GetFields ()
578 return GetFields (DefaultBindingFlags);
581 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
583 public override int GetHashCode()
585 return (int)_impl.Value;
588 public MemberInfo[] GetMember( string name)
590 return GetMember (name, DefaultBindingFlags);
593 public virtual MemberInfo[] GetMember( string name, BindingFlags bindingAttr)
595 return GetMember (name, MemberTypes.All, bindingAttr);
598 public virtual MemberInfo[] GetMember (string name, MemberTypes type,
599 BindingFlags bindingAttr)
601 return FindMembers (type, bindingAttr, FilterName, name);
604 public MemberInfo[] GetMembers()
606 return GetMembers (DefaultBindingFlags);
609 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
611 public MethodInfo GetMethod (string name)
614 throw new ArgumentNullException ("name");
615 return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
618 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
621 throw new ArgumentNullException ("name");
623 return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
626 public MethodInfo GetMethod (string name, Type[] types)
628 return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
631 public MethodInfo GetMethod( string name, Type[] types, ParameterModifier[] modifiers)
633 return GetMethod (name, DefaultBindingFlags, null,
634 CallingConventions.Any, types, modifiers);
637 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
638 Type[] types, ParameterModifier[] modifiers)
641 return GetMethod (name, bindingAttr, binder,
642 CallingConventions.Any, types, modifiers);
645 public MethodInfo GetMethod (string name, BindingFlags bindingAttr,
646 Binder binder, CallingConventions callConvention,
647 Type[] types, ParameterModifier[] modifiers)
650 throw new ArgumentNullException ("name");
652 throw new ArgumentNullException ("types");
654 for (int i = 0; i < types.Length; i++)
655 if (types[i] == null)
656 throw new ArgumentNullException ("types");
658 return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
661 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
663 CallingConventions callConvention,
664 Type[] types, ParameterModifier[] modifiers);
666 public MethodInfo[] GetMethods ()
668 return GetMethods (DefaultBindingFlags);
671 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
673 public Type GetNestedType (string name)
675 return GetNestedType (name, DefaultBindingFlags);
678 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
680 public Type[] GetNestedTypes ()
682 return GetNestedTypes (DefaultBindingFlags);
685 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
688 public PropertyInfo[] GetProperties ()
690 return GetProperties (DefaultBindingFlags);
693 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
696 public PropertyInfo GetProperty (string name)
699 throw new ArgumentNullException ("name");
701 return GetPropertyImpl (name, DefaultBindingFlags, null, null, new Type[0], null);
704 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
707 throw new ArgumentNullException ("name");
708 return GetPropertyImpl (name, bindingAttr, null, null, new Type[0], null);
711 public PropertyInfo GetProperty (string name, Type returnType)
714 throw new ArgumentNullException ("name");
715 return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, new Type[0], null);
718 public PropertyInfo GetProperty (string name, Type[] types)
720 return GetProperty (name, DefaultBindingFlags, null, null, types, null);
723 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
725 return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
728 public PropertyInfo GetProperty( string name, Type returnType, Type[] types,
729 ParameterModifier[] modifiers)
731 return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
734 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr,
735 Binder binder, Type returnType,
736 Type[] types, ParameterModifier[] modifiers)
739 throw new ArgumentNullException ("name");
741 throw new ArgumentNullException ("types");
743 return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
746 protected abstract PropertyInfo GetPropertyImpl (string name,
747 BindingFlags bindingAttr,
748 Binder binder, Type returnType,
750 ParameterModifier[] modifiers);
752 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
754 CallingConventions callConvention,
756 ParameterModifier[] modifiers);
758 protected abstract TypeAttributes GetAttributeFlagsImpl ();
759 protected abstract bool HasElementTypeImpl ();
760 protected abstract bool IsArrayImpl ();
761 protected abstract bool IsByRefImpl ();
762 protected abstract bool IsCOMObjectImpl ();
763 protected abstract bool IsPointerImpl ();
764 protected abstract bool IsPrimitiveImpl ();
766 [MethodImplAttribute(MethodImplOptions.InternalCall)]
767 internal static extern bool IsArrayImpl (Type type);
769 protected virtual bool IsValueTypeImpl ()
771 if (this == typeof (Enum) || this == typeof (ValueType))
774 return IsSubclassOf (typeof (ValueType));
777 protected virtual bool IsContextfulImpl ()
779 return typeof (ContextBoundObject).IsAssignableFrom (this);
782 protected virtual bool IsMarshalByRefImpl ()
784 return typeof (MarshalByRefObject).IsAssignableFrom (this);
787 public ConstructorInfo GetConstructor (Type[] types)
789 return GetConstructorImpl (
790 DefaultBindingFlags, null, CallingConventions.Any, types, null);
793 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
794 Type[] types, ParameterModifier[] modifiers)
796 return GetConstructorImpl (
797 bindingAttr, binder, CallingConventions.Any, types, modifiers);
800 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
801 CallingConventions callConvention,
802 Type[] types, ParameterModifier[] modifiers)
805 throw new ArgumentNullException ("types");
807 return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
810 public ConstructorInfo[] GetConstructors ()
812 return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
815 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
817 public virtual MemberInfo[] GetDefaultMembers ()
819 object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
821 return new MemberInfo [0];
823 MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
824 return (member != null) ? member : new MemberInfo [0];
827 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
828 MemberFilter filter, object filterCriteria)
831 ArrayList l = new ArrayList ();
833 // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
834 // this.FullName, this.GetType().FullName, this.obj_address());
836 if ((memberType & MemberTypes.Constructor) != 0) {
837 ConstructorInfo[] c = GetConstructors (bindingAttr);
838 if (filter != null) {
839 foreach (MemberInfo m in c) {
840 if (filter (m, filterCriteria))
847 if ((memberType & MemberTypes.Event) != 0) {
848 EventInfo[] c = GetEvents (bindingAttr);
849 if (filter != null) {
850 foreach (MemberInfo m in c) {
851 if (filter (m, filterCriteria))
858 if ((memberType & MemberTypes.Field) != 0) {
859 FieldInfo[] c = GetFields (bindingAttr);
860 if (filter != null) {
861 foreach (MemberInfo m in c) {
862 if (filter (m, filterCriteria))
869 if ((memberType & MemberTypes.Method) != 0) {
870 MethodInfo[] c = GetMethods (bindingAttr);
871 if (filter != null) {
872 foreach (MemberInfo m in c) {
873 if (filter (m, filterCriteria))
880 if ((memberType & MemberTypes.Property) != 0) {
884 if (filter != null) {
886 while ((l.Count == count) && (ptype != null)) {
887 c = ptype.GetProperties (bindingAttr);
888 foreach (MemberInfo m in c) {
889 if (filter (m, filterCriteria))
892 ptype = ptype.BaseType;
895 c = GetProperties (bindingAttr);
899 if ((memberType & MemberTypes.NestedType) != 0) {
900 Type[] c = GetNestedTypes (bindingAttr);
901 if (filter != null) {
902 foreach (MemberInfo m in c) {
903 if (filter (m, filterCriteria)) {
911 result = new MemberInfo [l.Count];
916 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
917 object target, object[] args)
919 return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
922 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
923 object target, object[] args, CultureInfo culture)
925 return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
928 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
929 Binder binder, object target, object[] args,
930 ParameterModifier[] modifiers,
931 CultureInfo culture, string[] namedParameters);
933 public override string ToString()
939 [MethodImplAttribute(MethodImplOptions.InternalCall)]
940 public extern Type [] GetGenericArguments ();
942 public abstract bool HasGenericArguments {
946 public abstract bool ContainsGenericParameters {
950 public extern bool IsGenericTypeDefinition {
951 [MethodImplAttribute(MethodImplOptions.InternalCall)]
955 [MethodImplAttribute(MethodImplOptions.InternalCall)]
956 extern Type GetGenericTypeDefinition_impl ();
958 public virtual Type GetGenericTypeDefinition ()
960 Type res = GetGenericTypeDefinition_impl ();
962 throw new InvalidOperationException ();
967 public extern bool IsGenericInstance {
968 [MethodImplAttribute(MethodImplOptions.InternalCall)]
972 [MethodImplAttribute(MethodImplOptions.InternalCall)]
973 static extern Type BindGenericParameters (Type gt, Type [] types);
975 public Type BindGenericParameters (Type [] types)
978 throw new ArgumentNullException ("types");
979 foreach (Type t in types) {
981 throw new ArgumentNullException ("types");
983 Type res = BindGenericParameters (this, types);
985 throw new TypeLoadException ();
989 public abstract bool IsGenericParameter {
993 [MethodImplAttribute(MethodImplOptions.InternalCall)]
994 extern int GetGenericParameterPosition ();
996 public virtual int GenericParameterPosition {
998 int res = GetGenericParameterPosition ();
1000 throw new InvalidOperationException ();
1005 public abstract MethodInfo DeclaringMethod {
1009 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1010 extern Type make_array_type (int rank);
1012 public virtual Type MakeArrayType ()
1014 return MakeArrayType (1);
1017 public virtual Type MakeArrayType (int rank)
1020 throw new IndexOutOfRangeException ();
1021 return make_array_type (rank);
1024 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1025 extern Type make_byref_type ();
1027 public virtual Type MakeByRefType ()
1029 return make_byref_type ();