3 // Copyright (c) Microsoft Corporation. All rights reserved.
9 // <OWNER>[....]</OWNER>
11 // Implements System.RuntimeType
13 // ======================================================================================
17 using System.Reflection;
18 using System.Runtime.ConstrainedExecution;
19 using System.Globalization;
20 using System.Threading;
21 using System.Diagnostics;
22 using System.Security.Permissions;
23 using System.Collections;
24 using System.Collections.Generic;
26 using System.Runtime.Serialization;
27 using System.Runtime.CompilerServices;
28 using System.Security;
30 using System.Runtime.Remoting;
32 using System.Runtime.Remoting.Proxies;
33 using System.Runtime.Remoting.Messaging;
34 using System.Runtime.Remoting.Activation;
35 using System.Runtime.Remoting.Metadata;
38 using MdSigCallingConvention = System.Signature.MdSigCallingConvention;
39 using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
41 using System.Runtime.InteropServices;
42 using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
44 using MdToken = System.Reflection.MetadataToken;
46 using System.Runtime.Versioning;
47 using System.Diagnostics.Contracts;
50 using CustomAttribute=System.MonoCustomAttrs;
55 // this is a work around to get the concept of a calli. It's not as fast but it would be interesting to
56 // see how it compares to the current implementation.
57 // This delegate will disappear at some point in favor of calli
59 internal delegate void CtorDelegate(Object instance);
61 // Keep this in [....] with FormatFlags defined in typestring.h
62 internal enum TypeNameFormatFlags
64 FormatBasic = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
65 FormatNamespace = 0x00000001, // Include namespace and/or enclosing class names in type names
66 FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
67 FormatAssembly = 0x00000004, // Include assembly display name in type names
68 FormatSignature = 0x00000008, // Include signature in method names
69 FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names
71 FormatDebug = 0x00000020, // For debug printing of types only
73 FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
74 FormatStubInfo = 0x00000080, // Include stub info like {unbox-stub}
75 FormatGenericParam = 0x00000100, // Use !name and !!name for generic type and method parameters
77 // If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
78 // we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
79 // and including the assembly name will normally increase the size of the serialized data and also decrease the performance.
80 FormatSerialization = FormatNamespace |
85 internal enum TypeNameKind
94 internal partial class RuntimeType :
95 System.Reflection.TypeInfo, ISerializable, ICloneable
99 internal enum MemberListType
107 // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
108 private struct ListBuilder<T> where T : class
115 public ListBuilder(int capacity)
120 _capacity = capacity;
123 public T this[int index]
127 Contract.Requires(index < Count);
128 return (_items != null) ? _items[index] : _item;
130 #if FEATURE_LEGACYNETCF
131 // added for Dev11 466969 quirk
134 Contract.Requires(index < Count);
136 _items[index] = value;
146 return EmptyArray<T>.Value;
148 return new T[1] { _item };
150 Array.Resize(ref _items, _count);
155 public void CopyTo(Object[] array, int index)
162 array[index] = _item;
166 Array.Copy(_items, 0, array, index, _count);
177 public void Add(T item)
189 _items = new T[_capacity];
193 if (_capacity == _count)
195 int newCapacity = 2 * _capacity;
196 Array.Resize(ref _items, newCapacity);
197 _capacity = newCapacity;
200 _items[_count] = item;
206 internal class RuntimeTypeCache
208 private const int MAXNAMELEN = 1024;
211 internal enum CacheType
222 private struct Filter
224 private Utf8String m_name;
225 private MemberListType m_listType;
226 private uint m_nameHash;
228 [System.Security.SecurityCritical] // auto-generated
229 public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
231 this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
232 this.m_listType = listType;
235 if (RequiresStringComparison())
237 m_nameHash = m_name.HashCaseInsensitive();
241 public bool Match(Utf8String name)
245 if (m_listType == MemberListType.CaseSensitive)
246 retVal = m_name.Equals(name);
247 else if (m_listType == MemberListType.CaseInsensitive)
248 retVal = m_name.EqualsCaseInsensitive(name);
250 // Currently the callers of UsesStringComparison assume that if it returns false
251 // then the match always succeeds and can be skipped. Assert that this is maintained.
252 Contract.Assert(retVal || RequiresStringComparison());
257 // Does the current match type require a string comparison?
258 // If not, we know Match will always return true and the call can be skipped
259 // If so, we know we can have a valid hash to check against from GetHashToMatch
260 public bool RequiresStringComparison()
262 return (m_listType == MemberListType.CaseSensitive) ||
263 (m_listType == MemberListType.CaseInsensitive);
266 public bool CaseSensitive()
268 return (m_listType == MemberListType.CaseSensitive);
271 public uint GetHashToMatch()
273 Contract.Assert(RequiresStringComparison());
279 private class MemberInfoCache<T> where T : MemberInfo
281 #region Private Data Members
284 private CerHashtable<string, T[]> m_csMemberInfos;
285 private CerHashtable<string, T[]> m_cisMemberInfos;
286 // List of MemberInfos given out. When m_cacheComplete is false, it may have null entries at the end to avoid
287 // reallocating the list every time a new entry is added.
288 private T[] m_allMembers;
289 private bool m_cacheComplete;
290 #if FEATURE_LEGACYNETCF
291 // Dev11 466969 quirk
292 private List<RuntimePropertyInfo> m_ambiguousProperties;
295 // This is the strong reference back to the cache
296 private RuntimeTypeCache m_runtimeTypeCache;
301 [System.Security.SecuritySafeCritical] // auto-generated
303 internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
306 Mda.MemberInfoCacheCreation();
308 m_runtimeTypeCache = runtimeTypeCache;
311 #if FEATURE_LEGACYNETCF
312 // Dev11 466969 quirk
313 internal IReadOnlyList<RuntimePropertyInfo> AmbiguousProperties { get { return m_ambiguousProperties; } }
315 private void InitializeAndUpdateAmbiguousPropertiesList(RuntimePropertyInfo parent, RuntimePropertyInfo child)
317 Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
319 if (m_ambiguousProperties == null)
321 List<RuntimePropertyInfo> newList = new List<RuntimePropertyInfo>();
322 Interlocked.CompareExchange(ref m_ambiguousProperties, newList, null);
325 lock (m_ambiguousProperties)
327 // record the parent type in case it needs to be pruned later.
328 Contract.Assert(child.DeclaringType.IsSubclassOf(parent.DeclaringType));
329 m_ambiguousProperties.Add(parent);
334 [System.Security.SecuritySafeCritical] // auto-generated
335 internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
338 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method);
339 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
340 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
341 bool isInherited = declaringType != ReflectedType;
342 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
345 case CacheType.Method:
346 list = (T[])(object)new RuntimeMethodInfo[1] {
347 new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null)
350 case CacheType.Constructor:
351 list = (T[])(object)new RuntimeConstructorInfo[1] {
352 new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)
357 Insert(ref list, null, MemberListType.HandleToInfo);
359 return (MethodBase)(object)list[0];
362 [System.Security.SecuritySafeCritical] // auto-generated
363 internal FieldInfo AddField(RuntimeFieldHandleInternal field)
365 // create the runtime field info
366 FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field);
367 bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
368 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
369 RuntimeType approxDeclaringType = RuntimeFieldHandle.GetApproxDeclaringType(field);
370 bool isInherited = RuntimeFieldHandle.AcquiresContextFromThis(field) ?
371 !RuntimeTypeHandle.CompareCanonicalHandles(approxDeclaringType, ReflectedType) :
372 approxDeclaringType != ReflectedType;
374 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
376 T[] list = (T[])(object)new RuntimeFieldInfo[1] {
377 new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags)
380 Insert(ref list, null, MemberListType.HandleToInfo);
382 return (FieldInfo)(object)list[0];
385 [System.Security.SecuritySafeCritical] // auto-generated
386 private unsafe T[] Populate(string name, MemberListType listType, CacheType cacheType)
390 if (name == null || name.Length == 0 ||
391 (cacheType == CacheType.Constructor && name.FirstChar != '.' && name.FirstChar != '*'))
393 list = GetListByName(null, 0, null, 0, listType, cacheType);
397 int cNameLen = name.Length;
398 fixed (char* pName = name)
400 int cUtf8Name = Encoding.UTF8.GetByteCount(pName, cNameLen);
401 // allocating on the stack is faster than allocating on the GC heap
402 // but we surely don't want to cause a stack overflow
403 // no one should be looking for a member whose name is longer than 1024
404 if (cUtf8Name > MAXNAMELEN)
406 fixed (byte* pUtf8Name = new byte[cUtf8Name])
408 list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
413 byte* pUtf8Name = stackalloc byte[cUtf8Name];
414 list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
419 Insert(ref list, name, listType);
424 [System.Security.SecurityCritical] // auto-generated
425 private unsafe T[] GetListByName(char* pName, int cNameLen, byte* pUtf8Name, int cUtf8Name, MemberListType listType, CacheType cacheType)
428 Encoding.UTF8.GetBytes(pName, cNameLen, pUtf8Name, cUtf8Name);
430 Filter filter = new Filter(pUtf8Name, cUtf8Name, listType);
435 case CacheType.Method:
436 list = PopulateMethods(filter);
438 case CacheType.Field:
439 list = PopulateFields(filter);
441 case CacheType.Constructor:
442 list = PopulateConstructors(filter);
444 case CacheType.Property:
445 list = PopulateProperties(filter);
447 case CacheType.Event:
448 list = PopulateEvents(filter);
450 case CacheType.NestedType:
451 list = PopulateNestedClasses(filter);
453 case CacheType.Interface:
454 list = PopulateInterfaces(filter);
457 BCLDebug.Assert(true, "Invalid CacheType");
464 // May replace the list with a new one if certain cache
465 // lookups succeed. Also, may modify the contents of the list
466 // after merging these new data structures with cached ones.
467 [System.Security.SecuritySafeCritical] // auto-generated
468 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
469 internal void Insert(ref T[] list, string name, MemberListType listType)
471 bool lockTaken = false;
473 RuntimeHelpers.PrepareConstrainedRegions();
476 Monitor.Enter(this, ref lockTaken);
480 case MemberListType.CaseSensitive:
482 // Ensure we always return a list that has
483 // been merged with the global list.
484 T[] cachedList = m_csMemberInfos[name];
485 if (cachedList == null)
487 MergeWithGlobalList(list);
488 m_csMemberInfos[name] = list;
495 case MemberListType.CaseInsensitive:
497 // Ensure we always return a list that has
498 // been merged with the global list.
499 T[] cachedList = m_cisMemberInfos[name];
500 if (cachedList == null)
502 MergeWithGlobalList(list);
503 m_cisMemberInfos[name] = list;
510 case MemberListType.All:
511 if (!m_cacheComplete)
513 MergeWithGlobalList(list);
515 // Trim null entries at the end of m_allMembers array
516 int memberCount = m_allMembers.Length;
517 while (memberCount > 0)
519 if (m_allMembers[memberCount-1] != null)
523 Array.Resize(ref m_allMembers, memberCount);
525 Volatile.Write(ref m_cacheComplete, true);
527 // We want the behavior where the results are returned in the same order on the phone
528 #if !FEATURE_LEGACYNETCF
535 MergeWithGlobalList(list);
548 // Modifies the existing list.
549 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
550 private void MergeWithGlobalList(T[] list)
552 T[] cachedMembers = m_allMembers;
554 if (cachedMembers == null)
560 int cachedCount = cachedMembers.Length;
561 int freeSlotIndex = 0;
563 for (int i = 0; i < list.Length; i++)
565 T newMemberInfo = list[i];
566 bool foundInCache = false;
569 for (cachedIndex = 0; cachedIndex < cachedCount; cachedIndex++)
571 T cachedMemberInfo = cachedMembers[cachedIndex];
572 if (cachedMemberInfo == null)
575 if (newMemberInfo.CacheEquals(cachedMemberInfo))
577 list[i] = cachedMemberInfo;
585 if (freeSlotIndex == 0)
586 freeSlotIndex = cachedIndex;
588 if (freeSlotIndex >= cachedMembers.Length)
594 // In theory, we should never add more elements to the cache when it is complete.
596 // Unfortunately, we shipped with bugs that cause changes of the complete cache (DevDiv #339308).
597 // Grow the list by exactly one element in this case to avoid null entries at the end.
600 // DevDiv #339308 is fixed, but we are keeping this code here for Dev11 in case there are other instances of this bug.
603 Contract.Assert(false);
605 newSize = cachedMembers.Length + 1;
609 newSize = Math.Max(Math.Max(4, 2 * cachedMembers.Length), list.Length);
612 // Use different variable for ref argument to Array.Resize to allow enregistration of cachedMembers by the JIT
613 T[] cachedMembers2 = cachedMembers;
614 Array.Resize(ref cachedMembers2, newSize);
615 cachedMembers = cachedMembers2;
618 Contract.Assert(cachedMembers[freeSlotIndex] == null);
619 cachedMembers[freeSlotIndex] = newMemberInfo;
624 m_allMembers = cachedMembers;
628 #region Population Logic
630 [System.Security.SecuritySafeCritical] // auto-generated
631 private unsafe RuntimeMethodInfo[] PopulateMethods(Filter filter)
633 ListBuilder<RuntimeMethodInfo> list = new ListBuilder<RuntimeMethodInfo>();
635 RuntimeType declaringType = ReflectedType;
636 Contract.Assert(declaringType != null);
638 if (RuntimeTypeHandle.IsInterface(declaringType))
642 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
644 if (filter.RequiresStringComparison())
646 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
648 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
652 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
656 #region Loop through all methods on the interface
657 Contract.Assert(!methodHandle.IsNullHandle());
658 // Except for .ctor, .cctor, IL_STUB*, and static methods, all interface methods should be abstract, virtual, and non-RTSpecialName.
659 // Note that this assumption will become invalid when we add support for non-abstract or static methods on interfaces.
661 (RuntimeMethodHandle.GetAttributes(methodHandle) & (MethodAttributes.RTSpecialName | MethodAttributes.Abstract | MethodAttributes.Virtual)) == (MethodAttributes.Abstract | MethodAttributes.Virtual) ||
662 (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.Static) == MethodAttributes.Static ||
663 RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
664 RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor") ||
665 RuntimeMethodHandle.GetName(methodHandle).StartsWith("IL_STUB", StringComparison.Ordinal));
667 #region Calculate Binding Flags
668 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
669 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
670 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
671 bool isInherited = false;
672 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
675 if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
678 // get the unboxing stub or instantiating stub if needed
679 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
681 RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
682 instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
684 list.Add(runtimeMethodInfo);
691 #region IsClass or GenericParameter
692 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
693 declaringType = declaringType.GetBaseType();
695 bool* overrides = stackalloc bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
696 bool isValueType = declaringType.IsValueType;
700 int vtableSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
702 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
704 if (filter.RequiresStringComparison())
706 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
708 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
712 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
716 #region Loop through all methods on the current type
717 Contract.Assert(!methodHandle.IsNullHandle());
719 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
720 MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;
722 #region Continue if this is a constructor
724 (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.RTSpecialName) == 0 ||
725 RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
726 RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor"));
728 if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
732 #region Continue if this is a private declared on a base type
733 bool isVirtual = false;
735 if ((methodAttributes & MethodAttributes.Virtual) != 0)
737 // only virtual if actually in the vtableslot range, but GetSlot will
738 // assert if an EnC method, which can't be virtual, so narrow down first
739 // before calling GetSlot
740 methodSlot = RuntimeMethodHandle.GetSlot(methodHandle);
741 isVirtual = (methodSlot < vtableSlots);
744 bool isInherited = declaringType != ReflectedType;
746 // NetCF actually includes private methods from parent classes in Reflection results
747 // We will mimic that in Mango Compat mode.
748 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
750 bool isPrivate = methodAccess == MethodAttributes.Private;
751 if (isInherited && isPrivate && !isVirtual)
756 #region Continue if this is a virtual and is already overridden
760 (methodAttributes & MethodAttributes.Abstract) != 0 ||
761 (methodAttributes & MethodAttributes.Virtual) != 0 ||
762 RuntimeMethodHandle.GetDeclaringType(methodHandle) != declaringType);
764 if (overrides[methodSlot] == true)
767 overrides[methodSlot] = true;
769 else if (isValueType)
771 if ((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) != 0)
776 Contract.Assert((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0);
780 #region Calculate Binding Flags
781 bool isPublic = methodAccess == MethodAttributes.Public;
782 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
783 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
786 // get the unboxing stub or instantiating stub if needed
787 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
789 RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
790 instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
792 list.Add(runtimeMethodInfo);
796 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
797 } while (declaringType != null);
801 return list.ToArray();
804 [System.Security.SecuritySafeCritical] // auto-generated
805 private RuntimeConstructorInfo[] PopulateConstructors(Filter filter)
807 if (ReflectedType.IsGenericParameter)
809 return EmptyArray<RuntimeConstructorInfo>.Value;
812 ListBuilder<RuntimeConstructorInfo> list = new ListBuilder<RuntimeConstructorInfo>();
814 RuntimeType declaringType= ReflectedType;
816 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
818 if (filter.RequiresStringComparison())
820 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
822 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
826 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
830 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
832 Contract.Assert(!methodHandle.IsNullHandle());
834 if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
837 // Constructors should not be virtual or abstract
839 (methodAttributes & MethodAttributes.Abstract) == 0 &&
840 (methodAttributes & MethodAttributes.Virtual) == 0);
842 #region Calculate Binding Flags
843 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
844 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
845 bool isInherited = false;
846 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
849 // get the unboxing stub or instantiating stub if needed
850 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
852 RuntimeConstructorInfo runtimeConstructorInfo =
853 new RuntimeConstructorInfo(instantiatedHandle, ReflectedType, m_runtimeTypeCache, methodAttributes, bindingFlags);
855 list.Add(runtimeConstructorInfo);
858 return list.ToArray();
861 [System.Security.SecuritySafeCritical] // auto-generated
862 private unsafe RuntimeFieldInfo[] PopulateFields(Filter filter)
864 ListBuilder<RuntimeFieldInfo> list = new ListBuilder<RuntimeFieldInfo>();
866 RuntimeType declaringType = ReflectedType;
868 #region Populate all static, instance and literal fields
869 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
870 declaringType = declaringType.GetBaseType();
872 while(declaringType != null)
874 PopulateRtFields(filter, declaringType, ref list);
876 PopulateLiteralFields(filter, declaringType, ref list);
878 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
882 #region Populate Literal Fields on Interfaces
883 if (ReflectedType.IsGenericParameter)
885 Type[] interfaces = ReflectedType.BaseType.GetInterfaces();
887 for (int i = 0; i < interfaces.Length; i++)
889 // Populate literal fields defined on any of the interfaces implemented by the declaring type
890 PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
891 PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
896 Type[] interfaces = RuntimeTypeHandle.GetInterfaces(ReflectedType);
898 if (interfaces != null)
900 for (int i = 0; i < interfaces.Length; i++)
902 // Populate literal fields defined on any of the interfaces implemented by the declaring type
903 PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
904 PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
910 return list.ToArray();
913 [System.Security.SecuritySafeCritical] // auto-generated
914 private unsafe void PopulateRtFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
916 IntPtr* pResult = stackalloc IntPtr[64];
919 if (!RuntimeTypeHandle.GetFields(declaringType, pResult, &count))
921 fixed(IntPtr* pBigResult = new IntPtr[count])
923 RuntimeTypeHandle.GetFields(declaringType, pBigResult, &count);
924 PopulateRtFields(filter, pBigResult, count, declaringType, ref list);
929 PopulateRtFields(filter, pResult, count, declaringType, ref list);
933 [System.Security.SecurityCritical] // auto-generated
934 private unsafe void PopulateRtFields(Filter filter,
935 IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
937 Contract.Requires(declaringType != null);
938 Contract.Requires(ReflectedType != null);
940 bool needsStaticFieldForGeneric = RuntimeTypeHandle.HasInstantiation(declaringType) && !RuntimeTypeHandle.ContainsGenericVariables(declaringType);
941 bool isInherited = declaringType != ReflectedType;
943 for(int i = 0; i < count; i ++)
945 RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(ppFieldHandles[i]);
947 if (filter.RequiresStringComparison())
949 if (!RuntimeFieldHandle.MatchesNameHash(runtimeFieldHandle, filter.GetHashToMatch()))
951 Contract.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
955 if (!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)))
959 Contract.Assert(!runtimeFieldHandle.IsNullHandle());
961 FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(runtimeFieldHandle);
962 FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
966 if (fieldAccess == FieldAttributes.Private)
970 #region Calculate Binding Flags
971 bool isPublic = fieldAccess == FieldAttributes.Public;
972 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
973 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
976 // correct the FieldDesc if needed
977 if (needsStaticFieldForGeneric && isStatic)
978 runtimeFieldHandle = RuntimeFieldHandle.GetStaticFieldForGenericType(runtimeFieldHandle, declaringType);
980 RuntimeFieldInfo runtimeFieldInfo =
981 new RtFieldInfo(runtimeFieldHandle, declaringType, m_runtimeTypeCache, bindingFlags);
983 list.Add(runtimeFieldInfo);
987 [System.Security.SecuritySafeCritical] // auto-generated
988 private unsafe void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
990 Contract.Requires(declaringType != null);
991 Contract.Requires(ReflectedType != null);
993 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
995 // Our policy is that TypeDescs do not have metadata tokens
996 if (MdToken.IsNullToken(tkDeclaringType))
999 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1001 MetadataEnumResult tkFields;
1002 scope.EnumFields(tkDeclaringType, out tkFields);
1004 for (int i = 0; i < tkFields.Length; i++)
1006 int tkField = tkFields[i];
1007 Contract.Assert(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
1008 Contract.Assert(!MdToken.IsNullToken(tkField));
1010 FieldAttributes fieldAttributes;
1011 scope.GetFieldDefProps(tkField, out fieldAttributes);
1013 FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
1015 if ((fieldAttributes & FieldAttributes.Literal) != 0)
1017 bool isInherited = declaringType != ReflectedType;
1020 bool isPrivate = fieldAccess == FieldAttributes.Private;
1025 if (filter.RequiresStringComparison())
1028 name = scope.GetName(tkField);
1030 if (!filter.Match(name))
1034 #region Calculate Binding Flags
1035 bool isPublic = fieldAccess == FieldAttributes.Public;
1036 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
1037 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
1040 RuntimeFieldInfo runtimeFieldInfo =
1041 new MdFieldInfo(tkField, fieldAttributes, declaringType.GetTypeHandleInternal(), m_runtimeTypeCache, bindingFlags);
1043 list.Add(runtimeFieldInfo);
1048 private static void AddElementTypes(Type template, IList<Type> types)
1050 if (!template.HasElementType)
1053 AddElementTypes(template.GetElementType(), types);
1055 for (int i = 0; i < types.Count; i ++)
1057 if (template.IsArray)
1059 if (template.IsSzArray)
1060 types[i] = types[i].MakeArrayType();
1062 types[i] = types[i].MakeArrayType(template.GetArrayRank());
1064 else if (template.IsPointer)
1066 types[i] = types[i].MakePointerType();
1071 private void AddSpecialInterface(ref ListBuilder<RuntimeType> list, Filter filter, RuntimeType iList, bool addSubInterface)
1073 if (iList.IsAssignableFrom(ReflectedType))
1075 if (filter.Match(RuntimeTypeHandle.GetUtf8Name(iList)))
1078 if (addSubInterface)
1080 Type[] iFaces = iList.GetInterfaces();
1081 for (int j = 0; j < iFaces.Length; j++)
1083 RuntimeType iFace = (RuntimeType)iFaces[j];
1084 if (iFace.IsGenericType && filter.Match(RuntimeTypeHandle.GetUtf8Name(iFace)))
1092 [System.Security.SecuritySafeCritical] // auto-generated
1093 private RuntimeType[] PopulateInterfaces(Filter filter)
1095 ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1097 RuntimeType declaringType = ReflectedType;
1099 if (!RuntimeTypeHandle.IsGenericVariable(declaringType))
1101 Type[] ifaces = RuntimeTypeHandle.GetInterfaces(declaringType);
1105 for (int i = 0; i < ifaces.Length; i++)
1107 RuntimeType interfaceType = (RuntimeType)ifaces[i];
1109 if (filter.RequiresStringComparison())
1111 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
1115 Contract.Assert(interfaceType.IsInterface);
1116 list.Add(interfaceType);
1120 if (ReflectedType.IsSzArray)
1122 RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType();
1124 if (!arrayType.IsPointer)
1126 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IList<>).MakeGenericType(arrayType), true);
1128 // To avoid adding a duplicate IEnumerable<T>, we don't add the sub interfaces of IReadOnlyList.
1129 // Instead, we add IReadOnlyCollection<T> separately.
1130 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyList<>).MakeGenericType(arrayType), false);
1131 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyCollection<>).MakeGenericType(arrayType), false);
1137 List<RuntimeType> al = new List<RuntimeType>();
1139 // Get all constraints
1140 Type[] constraints = declaringType.GetGenericParameterConstraints();
1142 // Populate transitive closure of all interfaces in constraint set
1143 for (int i = 0; i < constraints.Length; i++)
1145 RuntimeType constraint = (RuntimeType)constraints[i];
1146 if (constraint.IsInterface)
1149 Type[] temp = constraint.GetInterfaces();
1150 for (int j = 0; j < temp.Length; j++)
1151 al.Add(temp[j] as RuntimeType);
1154 // Remove duplicates
1155 Dictionary<RuntimeType, RuntimeType> ht = new Dictionary<RuntimeType, RuntimeType>();
1156 for (int i = 0; i < al.Count; i++)
1158 RuntimeType constraint = al[i];
1159 if (!ht.ContainsKey(constraint))
1160 ht[constraint] = constraint;
1163 RuntimeType[] interfaces = new RuntimeType[ht.Values.Count];
1164 ht.Values.CopyTo(interfaces, 0);
1166 // Populate link-list
1167 for (int i = 0; i < interfaces.Length; i++)
1169 if (filter.RequiresStringComparison())
1171 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaces[i])))
1175 list.Add(interfaces[i]);
1179 return list.ToArray();
1182 [System.Security.SecuritySafeCritical] // auto-generated
1183 private unsafe RuntimeType[] PopulateNestedClasses(Filter filter)
1185 RuntimeType declaringType = ReflectedType;
1187 while (RuntimeTypeHandle.IsGenericVariable(declaringType))
1189 declaringType = declaringType.GetBaseType();
1192 int tkEnclosingType = RuntimeTypeHandle.GetToken(declaringType);
1194 // For example, TypeDescs do not have metadata tokens
1195 if (MdToken.IsNullToken(tkEnclosingType))
1196 return EmptyArray<RuntimeType>.Value;
1198 ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1200 RuntimeModule moduleHandle = RuntimeTypeHandle.GetModule(declaringType);
1201 MetadataImport scope = ModuleHandle.GetMetadataImport(moduleHandle);
1203 MetadataEnumResult tkNestedClasses;
1204 scope.EnumNestedTypes(tkEnclosingType, out tkNestedClasses);
1206 for (int i = 0; i < tkNestedClasses.Length; i++)
1208 RuntimeType nestedType = null;
1212 nestedType = ModuleHandle.ResolveTypeHandleInternal(moduleHandle, tkNestedClasses[i], null, null);
1214 catch(System.TypeLoadException)
1216 // In a reflection emit scenario, we may have a token for a class which
1217 // has not been baked and hence cannot be loaded.
1221 if (filter.RequiresStringComparison())
1223 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(nestedType)))
1227 list.Add(nestedType);
1230 return list.ToArray();
1233 [System.Security.SecuritySafeCritical] // auto-generated
1234 private unsafe RuntimeEventInfo[] PopulateEvents(Filter filter)
1236 Contract.Requires(ReflectedType != null);
1238 // Do not create the dictionary if we are filtering the properties by name already
1239 Dictionary<String, RuntimeEventInfo> csEventInfos = filter.CaseSensitive() ? null :
1240 new Dictionary<String, RuntimeEventInfo>();
1242 RuntimeType declaringType = ReflectedType;
1243 ListBuilder<RuntimeEventInfo> list = new ListBuilder<RuntimeEventInfo>();
1245 if (!RuntimeTypeHandle.IsInterface(declaringType))
1247 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1248 declaringType = declaringType.GetBaseType();
1250 // Populate associates off of the class hierarchy
1251 while(declaringType != null)
1253 PopulateEvents(filter, declaringType, csEventInfos, ref list);
1254 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1259 // Populate associates for this interface
1260 PopulateEvents(filter, declaringType, csEventInfos, ref list);
1263 return list.ToArray();
1266 [System.Security.SecuritySafeCritical] // auto-generated
1267 private unsafe void PopulateEvents(
1268 Filter filter, RuntimeType declaringType, Dictionary<String, RuntimeEventInfo> csEventInfos, ref ListBuilder<RuntimeEventInfo> list)
1270 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1272 // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1273 if (MdToken.IsNullToken(tkDeclaringType))
1276 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1278 MetadataEnumResult tkEvents;
1279 scope.EnumEvents(tkDeclaringType, out tkEvents);
1281 for (int i = 0; i < tkEvents.Length; i++)
1283 int tkEvent = tkEvents[i];
1286 Contract.Assert(!MdToken.IsNullToken(tkEvent));
1287 Contract.Assert(MdToken.IsTokenOfType(tkEvent, MetadataTokenType.Event));
1289 if (filter.RequiresStringComparison())
1292 name = scope.GetName(tkEvent);
1294 if (!filter.Match(name))
1298 RuntimeEventInfo eventInfo = new RuntimeEventInfo(
1299 tkEvent, declaringType, m_runtimeTypeCache, out isPrivate);
1301 #region Remove Inherited Privates
1302 if (declaringType != m_runtimeTypeCache.GetRuntimeType() && isPrivate)
1306 #region Remove Duplicates
1307 if (csEventInfos != null)
1309 string name = eventInfo.Name;
1311 if (csEventInfos.GetValueOrDefault(name) != null)
1314 csEventInfos[name] = eventInfo;
1323 list.Add(eventInfo);
1327 [System.Security.SecuritySafeCritical] // auto-generated
1328 private unsafe RuntimePropertyInfo[] PopulateProperties(Filter filter)
1330 Contract.Requires(ReflectedType != null);
1332 // m_csMemberInfos can be null at this point. It will be initialized when Insert
1333 // is called in Populate after this returns.
1335 RuntimeType declaringType = ReflectedType;
1336 Contract.Assert(declaringType != null);
1338 ListBuilder<RuntimePropertyInfo> list = new ListBuilder<RuntimePropertyInfo>();
1340 if (!RuntimeTypeHandle.IsInterface(declaringType))
1342 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1343 declaringType = declaringType.GetBaseType();
1345 // Do not create the dictionary if we are filtering the properties by name already
1346 Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos = filter.CaseSensitive() ? null :
1347 new Dictionary<String, List<RuntimePropertyInfo>>();
1349 // All elements automatically initialized to false.
1350 bool[] usedSlots = new bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
1352 // Populate associates off of the class hierarchy
1355 PopulateProperties(filter, declaringType, csPropertyInfos, usedSlots, ref list);
1356 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1357 } while (declaringType != null);
1361 // Populate associates for this interface
1362 PopulateProperties(filter, declaringType, null, null, ref list);
1365 return list.ToArray();
1368 [System.Security.SecuritySafeCritical] // auto-generated
1369 private unsafe void PopulateProperties(
1371 RuntimeType declaringType,
1372 Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos,
1374 ref ListBuilder<RuntimePropertyInfo> list)
1376 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1378 // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1379 if (MdToken.IsNullToken(tkDeclaringType))
1382 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1384 MetadataEnumResult tkProperties;
1385 scope.EnumProperties(tkDeclaringType, out tkProperties);
1387 RuntimeModule declaringModuleHandle = RuntimeTypeHandle.GetModule(declaringType);
1389 int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType);
1391 Contract.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) ||
1392 (!declaringType.IsInterface && usedSlots != null && usedSlots.Length >= numVirtuals));
1394 for (int i = 0; i < tkProperties.Length; i++)
1396 int tkProperty = tkProperties[i];
1399 Contract.Assert(!MdToken.IsNullToken(tkProperty));
1400 Contract.Assert(MdToken.IsTokenOfType(tkProperty, MetadataTokenType.Property));
1402 if (filter.RequiresStringComparison())
1404 if (!ModuleHandle.ContainsPropertyMatchingHash(declaringModuleHandle, tkProperty, filter.GetHashToMatch()))
1406 Contract.Assert(!filter.Match(declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty)));
1411 name = declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty);
1413 if (!filter.Match(name))
1417 RuntimePropertyInfo propertyInfo =
1418 new RuntimePropertyInfo(
1419 tkProperty, declaringType, m_runtimeTypeCache, out isPrivate);
1421 // If this is a class, not an interface
1422 if (usedSlots != null)
1424 #region Remove Privates
1425 if (declaringType != ReflectedType && isPrivate)
1429 #region Duplicate check based on vtable slots
1431 // The inheritance of properties are defined by the inheritance of their
1432 // getters and setters.
1433 // A property on a base type is "overriden" by a property on a sub type
1434 // if the getter/setter of the latter occupies the same vtable slot as
1435 // the getter/setter of the former.
1437 MethodInfo associateMethod = propertyInfo.GetGetMethod();
1438 if (associateMethod == null)
1440 // We only need to examine the setter if a getter doesn't exist.
1441 // It is not logical for the getter to be virtual but not the setter.
1442 associateMethod = propertyInfo.GetSetMethod();
1445 if (associateMethod != null)
1447 int slot = RuntimeMethodHandle.GetSlot((RuntimeMethodInfo)associateMethod);
1449 if (slot < numVirtuals)
1451 Contract.Assert(associateMethod.IsVirtual);
1452 if (usedSlots[slot] == true)
1455 usedSlots[slot] = true;
1460 #region Duplicate check based on name and signature
1462 // For backward compatibility, even if the vtable slots don't match, we will still treat
1463 // a property as duplicate if the names and signatures match.
1465 if (csPropertyInfos != null)
1467 string name = propertyInfo.Name;
1469 List<RuntimePropertyInfo> cache = csPropertyInfos.GetValueOrDefault(name);
1473 cache = new List<RuntimePropertyInfo>(1);
1474 csPropertyInfos[name] = cache;
1477 for (int j = 0; j < cache.Count; j++)
1479 if (propertyInfo.EqualsSig(cache[j]))
1481 #if FEATURE_LEGACYNETCF
1482 // Dev11 466969 quirk
1483 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(cache[j]))
1485 InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, cache[j]);
1499 cache.Add(propertyInfo);
1503 bool duplicate = false;
1505 for (int j = 0; j < list.Count; j++)
1507 if (propertyInfo.EqualsSig(list[j]))
1509 #if FEATURE_LEGACYNETCF
1510 // Dev11 466969 quirk
1511 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(list[j]))
1513 InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, list[j]);
1530 list.Add(propertyInfo);
1535 #region NonPrivate Members
1536 internal T[] GetMemberList(MemberListType listType, string name, CacheType cacheType)
1542 case MemberListType.CaseSensitive:
1543 list = m_csMemberInfos[name];
1547 return Populate(name, listType, cacheType);
1549 case MemberListType.CaseInsensitive:
1550 list = m_cisMemberInfos[name];
1554 return Populate(name, listType, cacheType);
1557 Contract.Assert(listType == MemberListType.All);
1558 if (Volatile.Read(ref m_cacheComplete))
1559 return m_allMembers;
1561 return Populate(null, listType, cacheType);
1565 internal RuntimeType ReflectedType
1569 return m_runtimeTypeCache.GetRuntimeType();
1576 #region Private Data Members
1577 private RuntimeType m_runtimeType;
1578 private RuntimeType m_enclosingType;
1579 private TypeCode m_typeCode;
1580 private string m_name;
1581 private string m_fullname;
1582 private string m_toString;
1583 private string m_namespace;
1584 private string m_serializationname;
1585 private bool m_isGlobal;
1586 private bool m_bIsDomainInitialized;
1587 private MemberInfoCache<RuntimeMethodInfo> m_methodInfoCache;
1588 private MemberInfoCache<RuntimeConstructorInfo> m_constructorInfoCache;
1589 private MemberInfoCache<RuntimeFieldInfo> m_fieldInfoCache;
1590 private MemberInfoCache<RuntimeType> m_interfaceCache;
1591 private MemberInfoCache<RuntimeType> m_nestedClassesCache;
1592 private MemberInfoCache<RuntimePropertyInfo> m_propertyInfoCache;
1593 private MemberInfoCache<RuntimeEventInfo> m_eventInfoCache;
1594 private static CerHashtable<RuntimeMethodInfo, RuntimeMethodInfo> s_methodInstantiations;
1595 private static Object s_methodInstantiationsLock;
1596 #if !FEATURE_CORECLR
1597 private RuntimeConstructorInfo m_serializationCtor;
1599 private string m_defaultMemberName;
1600 private Object m_genericCache; // Generic cache for rare scenario specific data. It is used to cache Enum names and values.
1604 internal RuntimeTypeCache(RuntimeType runtimeType)
1606 m_typeCode = TypeCode.Empty;
1607 m_runtimeType = runtimeType;
1608 m_isGlobal = RuntimeTypeHandle.GetModule(runtimeType).RuntimeType == runtimeType;
1612 #region Private Members
1613 private string ConstructName(ref string name, TypeNameFormatFlags formatFlags)
1617 name = new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags);
1622 private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType)
1623 where T : MemberInfo
1625 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1626 return existingCache.GetMemberList(listType, name, cacheType);
1629 #if FEATURE_LEGACYNETCF
1630 // Dev11 466969 quirk
1631 private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
1632 where T : MemberInfo
1634 Contract.Assert(cacheType == CacheType.Property);
1636 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1637 T[] results = existingCache.GetMemberList(listType, name, cacheType);
1639 // must access property after GetMemberList() has been called
1640 ambiguousProperties = existingCache.AmbiguousProperties;
1642 // we should only have an ambiguous properties list in Mango-compat mode
1643 Contract.Assert(ambiguousProperties == null || CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
1648 private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T> m_cache)
1649 where T : MemberInfo
1651 MemberInfoCache<T> existingCache = m_cache;
1653 if (existingCache == null)
1655 MemberInfoCache<T> newCache = new MemberInfoCache<T>(this);
1656 existingCache = Interlocked.CompareExchange(ref m_cache, newCache, null);
1657 if (existingCache == null)
1658 existingCache = newCache;
1661 return existingCache;
1665 #region Internal Members
1667 internal Object GenericCache
1669 get { return m_genericCache; }
1670 set { m_genericCache = value; }
1673 internal bool DomainInitialized
1675 get { return m_bIsDomainInitialized; }
1676 set { m_bIsDomainInitialized = value; }
1679 internal string GetName(TypeNameKind kind)
1683 case TypeNameKind.Name:
1684 // No namespace, full instantiation, and assembly.
1685 return ConstructName(ref m_name, TypeNameFormatFlags.FormatBasic);
1687 case TypeNameKind.FullName:
1688 // We exclude the types that contain generic parameters because their names cannot be roundtripped.
1689 // We allow generic type definitions (and their refs, ptrs, and arrays) because their names can be roundtriped.
1690 // Theoretically generic types instantiated with generic type definitions can be roundtripped, e.g. List`1<Dictionary`2>.
1691 // But these kind of types are useless, rare, and hard to identity. We would need to recursively examine all the
1692 // generic arguments with the same criteria. We will exclude them unless we see a real user scenario.
1693 if (!m_runtimeType.GetRootElementType().IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters)
1697 return ConstructName(ref m_fullname, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst);
1699 case TypeNameKind.ToString:
1700 // No full instantiation and assembly.
1701 return ConstructName(ref m_toString, TypeNameFormatFlags.FormatNamespace);
1703 case TypeNameKind.SerializationName:
1704 // Use FormatGenericParam in serialization. Otherwise we won't be able
1705 // to distinguish between a generic parameter and a normal type with the same name.
1706 // e.g. Foo<T>.Bar(T t), the parameter type T could be !1 or a real type named "T".
1707 // Excluding the version number in the assembly name for VTS.
1708 return ConstructName(ref m_serializationname, TypeNameFormatFlags.FormatSerialization);
1711 throw new InvalidOperationException();
1715 [System.Security.SecuritySafeCritical]
1716 internal unsafe string GetNameSpace()
1718 // @Optimization - Use ConstructName to populate m_namespace
1719 if (m_namespace == null)
1721 Type type = m_runtimeType;
1722 type = type.GetRootElementType();
1724 while (type.IsNested)
1725 type = type.DeclaringType;
1727 m_namespace = RuntimeTypeHandle.GetMetadataImport((RuntimeType)type).GetNamespace(type.MetadataToken).ToString();
1733 internal TypeCode TypeCode
1735 get { return m_typeCode; }
1736 set { m_typeCode = value; }
1739 [System.Security.SecuritySafeCritical] // auto-generated
1740 internal unsafe RuntimeType GetEnclosingType()
1742 if (m_enclosingType == null)
1744 // Use void as a marker of null enclosing type
1745 RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
1746 Contract.Assert(enclosingType != typeof(void));
1747 m_enclosingType = enclosingType ?? (RuntimeType)typeof(void);
1750 return (m_enclosingType == typeof(void)) ? null : m_enclosingType;
1753 internal RuntimeType GetRuntimeType()
1755 return m_runtimeType;
1758 internal bool IsGlobal
1760 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1761 get { return m_isGlobal; }
1764 internal void InvalidateCachedNestedType()
1766 m_nestedClassesCache = null;
1769 #if !FEATURE_CORECLR
1770 internal RuntimeConstructorInfo GetSerializationCtor()
1772 if (m_serializationCtor == null)
1774 if (s_SICtorParamTypes == null)
1775 s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
1777 m_serializationCtor = m_runtimeType.GetConstructor(
1778 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
1780 CallingConventions.Any,
1782 null) as RuntimeConstructorInfo;
1785 return m_serializationCtor;
1787 #endif //!FEATURE_CORECLR
1789 internal string GetDefaultMemberName()
1791 if (m_defaultMemberName == null)
1793 CustomAttributeData attr = null;
1794 Type DefaultMemberAttrType = typeof(DefaultMemberAttribute);
1795 for (RuntimeType t = m_runtimeType; t != null; t = t.GetBaseType())
1797 IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes(t);
1798 for (int i = 0; i < attrs.Count; i++)
1800 if (Object.ReferenceEquals(attrs[i].Constructor.DeclaringType, DefaultMemberAttrType))
1809 m_defaultMemberName = attr.ConstructorArguments[0].Value as string;
1815 return m_defaultMemberName;
1819 #region Caches Accessors
1820 [System.Security.SecurityCritical] // auto-generated
1821 internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandleInternal genericMethod)
1823 LoaderAllocator la = RuntimeMethodHandle.GetLoaderAllocator(genericMethod);
1825 RuntimeMethodInfo rmi = new RuntimeMethodInfo(
1826 genericMethod, RuntimeMethodHandle.GetDeclaringType(genericMethod), this,
1827 RuntimeMethodHandle.GetAttributes(genericMethod), (BindingFlags)(-1), la);
1829 RuntimeMethodInfo crmi;
1832 crmi = la.m_methodInstantiations[rmi];
1836 crmi = s_methodInstantiations[rmi];
1841 if (s_methodInstantiationsLock == null)
1842 Interlocked.CompareExchange(ref s_methodInstantiationsLock, new Object(), null);
1844 bool lockTaken = false;
1845 RuntimeHelpers.PrepareConstrainedRegions();
1848 Monitor.Enter(s_methodInstantiationsLock, ref lockTaken);
1852 crmi = la.m_methodInstantiations[rmi];
1855 la.m_methodInstantiations[rmi] = rmi;
1859 crmi = s_methodInstantiations[rmi];
1862 s_methodInstantiations[rmi] = rmi;
1869 Monitor.Exit(s_methodInstantiationsLock);
1876 internal RuntimeMethodInfo[] GetMethodList(MemberListType listType, string name)
1878 return GetMemberList<RuntimeMethodInfo>(ref m_methodInfoCache, listType, name, CacheType.Method);
1881 internal RuntimeConstructorInfo[] GetConstructorList(MemberListType listType, string name)
1883 return GetMemberList<RuntimeConstructorInfo>(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
1886 internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name)
1888 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property);
1891 #if FEATURE_LEGACYNETCF
1892 // Dev11 466969 quirk
1893 internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
1895 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property, out ambiguousProperties);
1899 internal RuntimeEventInfo[] GetEventList(MemberListType listType, string name)
1901 return GetMemberList<RuntimeEventInfo>(ref m_eventInfoCache, listType, name, CacheType.Event);
1904 internal RuntimeFieldInfo[] GetFieldList(MemberListType listType, string name)
1906 return GetMemberList<RuntimeFieldInfo>(ref m_fieldInfoCache, listType, name, CacheType.Field);
1909 internal RuntimeType[] GetInterfaceList(MemberListType listType, string name)
1911 return GetMemberList<RuntimeType>(ref m_interfaceCache, listType, name, CacheType.Interface);
1914 internal RuntimeType[] GetNestedTypeList(MemberListType listType, string name)
1916 return GetMemberList<RuntimeType>(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
1919 internal MethodBase GetMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method)
1921 GetMemberCache<RuntimeMethodInfo>(ref m_methodInfoCache);
1922 return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method);
1925 internal MethodBase GetConstructor(RuntimeType declaringType, RuntimeMethodHandleInternal constructor)
1927 GetMemberCache<RuntimeConstructorInfo>(ref m_constructorInfoCache);
1928 return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor);
1931 internal FieldInfo GetField(RuntimeFieldHandleInternal field)
1933 GetMemberCache<RuntimeFieldInfo>(ref m_fieldInfoCache);
1934 return m_fieldInfoCache.AddField(field);
1942 #if FEATURE_REMOTING && !MONO
1943 #region Legacy Remoting Cache
1944 // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
1945 // This member is currently being used by Remoting for caching remoting data. If you
1946 // need to cache data here, talk to the Remoting team to work out a mechanism, so that
1947 // both caching systems can happily work together.
1948 private RemotingTypeCachedData m_cachedData;
1950 internal RemotingTypeCachedData RemotingCache
1954 // This grabs an internal copy of m_cachedData and uses
1955 // that instead of looking at m_cachedData directly because
1956 // the cache may get cleared asynchronously. This prevents
1957 // us from having to take a lock.
1958 RemotingTypeCachedData cache = m_cachedData;
1961 cache = new RemotingTypeCachedData(this);
1962 RemotingTypeCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
1970 #endif //FEATURE_REMOTING
1972 #region Static Members
1976 internal static RuntimeType GetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly,
1977 ref StackCrawlMark stackMark)
1979 if (typeName == null)
1980 throw new ArgumentNullException("typeName");
1981 Contract.EndContractBlock();
1983 #if FEATURE_LEGACYNETCF
1984 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && typeName.Length == 0)
1985 throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
1988 return RuntimeTypeHandle.GetTypeByName(
1989 typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
1992 internal static MethodBase GetMethodBase(RuntimeModule scope, int typeMetadataToken)
1994 return GetMethodBase(ModuleHandle.ResolveMethodHandleInternal(scope, typeMetadataToken));
1997 internal static MethodBase GetMethodBase(IRuntimeMethodInfo methodHandle)
1999 return GetMethodBase(null, methodHandle);
2002 [System.Security.SecuritySafeCritical]
2003 internal static MethodBase GetMethodBase(RuntimeType reflectedType, IRuntimeMethodInfo methodHandle)
2005 MethodBase retval = RuntimeType.GetMethodBase(reflectedType, methodHandle.Value);
2006 GC.KeepAlive(methodHandle);
2010 [System.Security.SecurityCritical] // auto-generated
2011 internal unsafe static MethodBase GetMethodBase(RuntimeType reflectedType, RuntimeMethodHandleInternal methodHandle)
2013 Contract.Assert(!methodHandle.IsNullHandle());
2015 if (RuntimeMethodHandle.IsDynamicMethod(methodHandle))
2017 Resolver resolver = RuntimeMethodHandle.GetResolver(methodHandle);
2019 if (resolver != null)
2020 return resolver.GetDynamicMethod();
2025 // verify the type/method relationship
2026 RuntimeType declaredType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
2028 RuntimeType[] methodInstantiation = null;
2030 if (reflectedType == null)
2031 reflectedType = declaredType as RuntimeType;
2033 if (reflectedType != declaredType && !reflectedType.IsSubclassOf(declaredType))
2035 // object[] is assignable from string[].
2036 if (reflectedType.IsArray)
2040 // The whole purpose of this chunk of code is not only for error checking.
2041 // GetMember has a side effect of populating the member cache of reflectedType,
2042 // doing so will ensure we construct the correct MethodInfo/ConstructorInfo objects.
2043 // Without this the reflectedType.Cache.GetMethod call below may return a MethodInfo
2044 // object whose ReflectedType is string[] and DeclaringType is object[]. That would
2045 // be (arguabally) incorrect because string[] is not a subclass of object[].
2046 MethodBase[] methodBases = reflectedType.GetMember(
2047 RuntimeMethodHandle.GetName(methodHandle), MemberTypes.Constructor | MemberTypes.Method,
2048 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) as MethodBase[];
2050 bool loaderAssuredCompatible = false;
2051 for (int i = 0; i < methodBases.Length; i++)
2053 IRuntimeMethodInfo rmi = (IRuntimeMethodInfo)methodBases[i];
2054 if (rmi.Value.Value == methodHandle.Value)
2055 loaderAssuredCompatible = true;
2058 if (!loaderAssuredCompatible)
2059 throw new ArgumentException(String.Format(
2060 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2061 reflectedType.ToString(), declaredType.ToString()));
2063 // Action<in string> is assignable from, but not a subclass of Action<in object>.
2064 else if (declaredType.IsGenericType)
2066 // ignoring instantiation is the ReflectedType a subtype of the DeclaringType
2067 RuntimeType declaringDefinition = (RuntimeType)declaredType.GetGenericTypeDefinition();
2069 RuntimeType baseType = reflectedType;
2071 while (baseType != null)
2073 RuntimeType baseDefinition = baseType;
2075 if (baseDefinition.IsGenericType && !baseType.IsGenericTypeDefinition)
2076 baseDefinition = (RuntimeType)baseDefinition.GetGenericTypeDefinition();
2078 if (baseDefinition == declaringDefinition)
2081 baseType = baseType.GetBaseType();
2084 if (baseType == null)
2086 // ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
2087 throw new ArgumentException(String.Format(
2088 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2089 reflectedType.ToString(), declaredType.ToString()));
2092 // remap the method to same method on the subclass ReflectedType
2093 declaredType = baseType;
2095 // if the original methodHandle was the definition then we don't need to rebind generic method arguments
2096 // because all RuntimeMethodHandles retrieved off of the canonical method table are definitions. That's
2097 // why for everything else we need to rebind the generic method arguments.
2098 if (!RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2100 methodInstantiation = RuntimeMethodHandle.GetMethodInstantiationInternal(methodHandle);
2103 // lookup via v-table slot the RuntimeMethodHandle on the new declaring type
2104 methodHandle = RuntimeMethodHandle.GetMethodFromCanonical(methodHandle, declaredType);
2106 else if (!declaredType.IsAssignableFrom(reflectedType))
2108 // declaredType is not Array, not generic, and not assignable from reflectedType
2109 throw new ArgumentException(String.Format(
2110 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2111 reflectedType.ToString(), declaredType.ToString()));
2115 // If methodInstantiation is not null, GetStubIfNeeded will rebind the generic method arguments
2116 // if declaredType is an instantiated generic type and methodHandle is not generic, get the instantiated MethodDesc (if needed)
2117 // if declaredType is a value type, get the unboxing stub (if needed)
2119 // this is so that our behavior here is consistent with that of Type.GetMethod
2120 // See MemberInfoCache<RuntimeConstructorInfo>.PopulateMethods and MemberInfoCache<RuntimeMethodInfoInfo>.PopulateConstructors
2122 methodHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaredType, methodInstantiation);
2125 if (RuntimeMethodHandle.IsConstructor(methodHandle))
2127 // Constructor case: constructors cannot be generic
2128 retval = reflectedType.Cache.GetConstructor(declaredType, methodHandle);
2133 if (RuntimeMethodHandle.HasMethodInstantiation(methodHandle) && !RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2134 retval = reflectedType.Cache.GetGenericMethodInfo(methodHandle);
2136 retval = reflectedType.Cache.GetMethod(declaredType, methodHandle);
2139 GC.KeepAlive(methodInstantiation);
2143 internal Object GenericCache
2145 get { return Cache.GenericCache; }
2146 set { Cache.GenericCache = value; }
2149 internal bool DomainInitialized
2151 get { return Cache.DomainInitialized; }
2152 set { Cache.DomainInitialized = value; }
2155 [System.Security.SecuritySafeCritical] // auto-generated
2156 internal unsafe static FieldInfo GetFieldInfo(IRuntimeFieldInfo fieldHandle)
2158 return GetFieldInfo(RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle), fieldHandle);
2161 [System.Security.SecuritySafeCritical] // auto-generated
2162 internal unsafe static FieldInfo GetFieldInfo(RuntimeType reflectedType, IRuntimeFieldInfo field)
2164 RuntimeFieldHandleInternal fieldHandle = field.Value;
2166 // verify the type/method relationship
2167 if (reflectedType == null)
2169 reflectedType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2173 RuntimeType declaredType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2174 if (reflectedType != declaredType)
2176 if (!RuntimeFieldHandle.AcquiresContextFromThis(fieldHandle) ||
2177 !RuntimeTypeHandle.CompareCanonicalHandles(declaredType, reflectedType))
2179 throw new ArgumentException(String.Format(
2180 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
2181 reflectedType.ToString(),
2182 declaredType.ToString()));
2187 FieldInfo retVal = reflectedType.Cache.GetField(fieldHandle);
2188 GC.KeepAlive(field);
2192 // Called internally
2193 private unsafe static PropertyInfo GetPropertyInfo(RuntimeType reflectedType, int tkProperty)
2195 RuntimePropertyInfo property = null;
2196 RuntimePropertyInfo[] candidates =
2197 reflectedType.Cache.GetPropertyList(MemberListType.All, null);
2199 for (int i = 0; i < candidates.Length; i++)
2201 property = candidates[i];
2202 if (property.MetadataToken == tkProperty)
2206 Contract.Assume(false, "Unreachable code");
2207 throw new SystemException();
2210 private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
2212 if (type.IsPointer || type.IsByRef || type == typeof(void))
2213 throw new ArgumentException(
2214 Environment.GetResourceString("Argument_NeverValidGenericArgument", type.ToString()));
2218 internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
2220 if (genericArguments == null)
2221 throw new ArgumentNullException();
2222 Contract.EndContractBlock();
2224 for(int i = 0; i < genericArguments.Length; i++)
2226 if (genericArguments[i] == null)
2227 throw new ArgumentNullException();
2229 ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
2232 if (genericArguments.Length != genericParamters.Length)
2233 throw new ArgumentException(
2234 Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
2237 [System.Security.SecuritySafeCritical] // auto-generated
2238 internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
2240 RuntimeType[] typeContext = null;
2241 RuntimeType[] methodContext = null;
2242 RuntimeType[] genericParamters = null;
2244 if (definition is Type)
2246 RuntimeType genericTypeDefinition = (RuntimeType)definition;
2247 genericParamters = genericTypeDefinition.GetGenericArgumentsInternal();
2248 typeContext = genericArguments;
2252 RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition;
2253 genericParamters = genericMethodDefinition.GetGenericArgumentsInternal();
2254 methodContext = genericArguments;
2256 RuntimeType declaringType = (RuntimeType)genericMethodDefinition.DeclaringType;
2257 if (declaringType != null)
2259 typeContext = declaringType.GetTypeHandleInternal().GetInstantiationInternal();
2263 for (int i = 0; i < genericArguments.Length; i++)
2265 Type genericArgument = genericArguments[i];
2266 Type genericParameter = genericParamters[i];
2268 if (!RuntimeTypeHandle.SatisfiesConstraints(genericParameter.GetTypeHandleInternal().GetTypeChecked(),
2269 typeContext, methodContext, genericArgument.GetTypeHandleInternal().GetTypeChecked()))
2271 throw new ArgumentException(
2272 Environment.GetResourceString("Argument_GenConstraintViolation",
2273 i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
2278 private static void SplitName(string fullname, out string name, out string ns)
2283 if (fullname == null)
2287 int nsDelimiter = fullname.LastIndexOf(".", StringComparison.Ordinal);
2288 if (nsDelimiter != -1 )
2290 ns = fullname.Substring(0, nsDelimiter);
2291 int nameLength = fullname.Length - ns.Length - 1;
2292 if (nameLength != 0)
2293 name = fullname.Substring(nsDelimiter + 1, nameLength);
2296 Contract.Assert(fullname.Equals(ns + "." + name));
2307 internal static BindingFlags FilterPreCalculate(bool isPublic, bool isInherited, bool isStatic)
2309 BindingFlags bindingFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
2313 // We arrange things so the DeclaredOnly flag means "include inherited members"
2314 bindingFlags |= BindingFlags.DeclaredOnly;
2318 bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
2322 bindingFlags |= BindingFlags.Instance;
2329 bindingFlags |= BindingFlags.Static;
2333 bindingFlags |= BindingFlags.Instance;
2337 return bindingFlags;
2340 // Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
2341 private static void FilterHelper(
2342 BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup,
2343 out bool ignoreCase, out MemberListType listType)
2345 prefixLookup = false;
2350 if ((bindingFlags & BindingFlags.IgnoreCase) != 0)
2352 name = name.ToLower(CultureInfo.InvariantCulture);
2354 listType = MemberListType.CaseInsensitive;
2358 listType = MemberListType.CaseSensitive;
2361 if (allowPrefixLookup && name.EndsWith("*", StringComparison.Ordinal))
2363 // We set prefixLookup to true if name ends with a "*".
2364 // We will also set listType to All so that all members are included in
2365 // the candidates which are later filtered by FilterApplyPrefixLookup.
2366 name = name.Substring(0, name.Length - 1);
2367 prefixLookup = true;
2368 listType = MemberListType.All;
2373 listType = MemberListType.All;
2377 // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported.
2378 private static void FilterHelper(BindingFlags bindingFlags, ref string name, out bool ignoreCase, out MemberListType listType)
2381 FilterHelper(bindingFlags, ref name, false, out prefixLookup, out ignoreCase, out listType);
2384 // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true.
2385 // Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
2386 private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase)
2388 Contract.Assert(name != null);
2392 if (!memberInfo.Name.StartsWith(name, StringComparison.OrdinalIgnoreCase))
2397 if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
2405 // Used by FilterApplyType to perform all the filtering based on name and BindingFlags
2406 private static bool FilterApplyBase(
2407 MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
2408 string name, bool prefixLookup)
2410 #region Preconditions
2411 Contract.Requires(memberInfo != null);
2412 Contract.Requires(name == null || (bindingFlags & BindingFlags.IgnoreCase) == 0 || (name.ToLower(CultureInfo.InvariantCulture).Equals(name)));
2415 #region Filter by Public & Private
2418 if ((bindingFlags & BindingFlags.Public) == 0)
2423 if ((bindingFlags & BindingFlags.NonPublic) == 0)
2428 bool isInherited = !Object.ReferenceEquals(memberInfo.DeclaringType, memberInfo.ReflectedType);
2430 #region Filter by DeclaredOnly
2431 if ((bindingFlags & BindingFlags.DeclaredOnly) != 0 && isInherited)
2435 #region Filter by Static & Instance
2436 if (memberInfo.MemberType != MemberTypes.TypeInfo &&
2437 memberInfo.MemberType != MemberTypes.NestedType)
2441 if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0 && isInherited)
2444 if ((bindingFlags & BindingFlags.Static) == 0)
2449 if ((bindingFlags & BindingFlags.Instance) == 0)
2455 #region Filter by name wrt prefixLookup and implicitly by case sensitivity
2456 if (prefixLookup == true)
2458 if (!FilterApplyPrefixLookup(memberInfo, name, (bindingFlags & BindingFlags.IgnoreCase) != 0))
2464 // @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned
2465 // iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
2466 if (((bindingFlags & BindingFlags.DeclaredOnly) == 0) && // DeclaredOnly not present
2467 isInherited && // Is inherited Member
2469 (isNonProtectedInternal) && // Is non-protected internal member
2470 ((bindingFlags & BindingFlags.NonPublic) != 0) && // BindingFlag.NonPublic present
2472 (!isStatic) && // Is instance member
2473 ((bindingFlags & BindingFlags.Instance) != 0)) // BindingFlag.Instance present
2475 MethodInfo methodInfo = memberInfo as MethodInfo;
2477 if (methodInfo == null)
2480 if (!methodInfo.IsVirtual && !methodInfo.IsAbstract)
2489 // Used by GetInterface and GetNestedType(s) which don't need parameter type filtering.
2490 private static bool FilterApplyType(
2491 Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns)
2493 Contract.Requires((object)type != null);
2494 Contract.Assert(type is RuntimeType);
2496 bool isPublic = type.IsNestedPublic || type.IsPublic;
2497 bool isStatic = false;
2499 if (!RuntimeType.FilterApplyBase(type, bindingFlags, isPublic, type.IsNestedAssembly, isStatic, name, prefixLookup))
2502 if (ns != null && !type.Namespace.Equals(ns))
2509 private static bool FilterApplyMethodInfo(
2510 RuntimeMethodInfo method, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2512 // Optimization: Pre-Calculate the method binding flags to avoid casting.
2513 return FilterApplyMethodBase(method, method.BindingFlags, bindingFlags, callConv, argumentTypes);
2516 private static bool FilterApplyConstructorInfo(
2517 RuntimeConstructorInfo constructor, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2519 // Optimization: Pre-Calculate the method binding flags to avoid casting.
2520 return FilterApplyMethodBase(constructor, constructor.BindingFlags, bindingFlags, callConv, argumentTypes);
2523 // Used by GetMethodCandidates/GetConstructorCandidates, InvokeMember, and CreateInstanceImpl to perform the necessary filtering.
2524 // Should only be called by FilterApplyMethodInfo and FilterApplyConstructorInfo.
2525 private static bool FilterApplyMethodBase(
2526 MethodBase methodBase, BindingFlags methodFlags, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2528 Contract.Requires(methodBase != null);
2530 bindingFlags ^= BindingFlags.DeclaredOnly;
2532 #region Apply Base Filter
2533 if ((bindingFlags & methodFlags) != methodFlags)
2537 #region Check CallingConvention
2538 if ((callConv & CallingConventions.Any) == 0)
2540 if ((callConv & CallingConventions.VarArgs) != 0 &&
2541 (methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2544 if ((callConv & CallingConventions.Standard) != 0 &&
2545 (methodBase.CallingConvention & CallingConventions.Standard) == 0)
2550 #region If argumentTypes supplied
2551 if (argumentTypes != null)
2553 ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy();
2555 if (argumentTypes.Length != parameterInfos.Length)
2557 #region Invoke Member, Get\Set & Create Instance specific case
2558 // If the number of supplied arguments differs than the number in the signature AND
2559 // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
2561 (BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
2564 bool testForParamArray = false;
2565 bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
2567 if (excessSuppliedArguments)
2568 { // more supplied arguments than parameters, additional arguments could be vararg
2570 // If method is not vararg, additional arguments can not be passed as vararg
2571 if ((methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2573 testForParamArray = true;
2577 // If Binding flags did not include varargs we would have filtered this vararg method.
2578 // This Invariant established during callConv check.
2579 Contract.Assert((callConv & CallingConventions.VarArgs) != 0);
2584 {// fewer supplied arguments than parameters, missing arguments could be optional
2585 #region OptionalParamBinding
2586 if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
2588 testForParamArray = true;
2592 // From our existing code, our policy here is that if a parameterInfo
2593 // is optional then all subsequent parameterInfos shall be optional.
2595 // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
2596 if (!parameterInfos[argumentTypes.Length].IsOptional)
2597 testForParamArray = true;
2603 if (testForParamArray)
2605 if (parameterInfos.Length == 0)
2608 // The last argument of the signature could be a param array.
2609 bool shortByMoreThanOneSuppliedArgument = argumentTypes.Length < parameterInfos.Length - 1;
2611 if (shortByMoreThanOneSuppliedArgument)
2614 ParameterInfo lastParameter = parameterInfos[parameterInfos.Length - 1];
2616 if (!lastParameter.ParameterType.IsArray)
2619 if (!lastParameter.IsDefined(typeof(ParamArrayAttribute), false))
2628 #region Exact Binding
2629 if ((bindingFlags & BindingFlags.ExactBinding) != 0)
2631 // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
2632 // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
2633 // all the rest of this to the binder too? Further, what other semanitc would the binder
2634 // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance
2635 // in this if statement? That's just InvokeMethod with a constructor, right?
2636 if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
2638 for(int i = 0; i < parameterInfos.Length; i ++)
2640 // a null argument type implies a null arg which is always a perfect match
2641 if ((object)argumentTypes[i] != null && !Object.ReferenceEquals(parameterInfos[i].ParameterType, argumentTypes[i]))
2658 #region Private Data Members
2660 private object m_keepalive; // This will be filled with a LoaderAllocator reference when this RuntimeType represents a collectible type
2661 private IntPtr m_cache;
2662 internal IntPtr m_handle;
2665 private INVOCATION_FLAGS m_invocationFlags;
2667 internal bool IsNonW8PFrameworkAPI()
2669 if (IsGenericParameter)
2673 return ((RuntimeType)GetElementType()).IsNonW8PFrameworkAPI();
2675 if (IsSimpleTypeNonW8PFrameworkAPI())
2678 if (IsGenericType && !IsGenericTypeDefinition)
2680 foreach (Type t in GetGenericArguments())
2682 if (((RuntimeType)t).IsNonW8PFrameworkAPI())
2690 private bool IsSimpleTypeNonW8PFrameworkAPI()
2692 RuntimeAssembly rtAssembly = GetRuntimeAssembly();
2693 if (rtAssembly.IsFrameworkAssembly())
2695 int ctorToken = rtAssembly.InvocableAttributeCtorToken;
2696 if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
2697 !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
2704 internal INVOCATION_FLAGS InvocationFlags
2708 if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
2710 INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
2712 if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
2713 invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
2715 m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
2718 return m_invocationFlags;
2721 #endif // FEATURE_APPX
2723 internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);
2724 internal static readonly RuntimeType EnumType = (RuntimeType)typeof(System.Enum);
2726 private static readonly RuntimeType ObjectType = (RuntimeType)typeof(System.Object);
2727 private static readonly RuntimeType StringType = (RuntimeType)typeof(System.String);
2728 private static readonly RuntimeType DelegateType = (RuntimeType)typeof(System.Delegate);
2730 private static Type[] s_SICtorParamTypes;
2734 internal RuntimeType() { throw new NotSupportedException(); }
2737 #region Private\Internal Members
2739 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
2740 internal override bool CacheEquals(object o)
2742 RuntimeType m = o as RuntimeType;
2747 return m.m_handle.Equals(m_handle);
2750 private RuntimeTypeCache Cache
2752 [System.Security.SecuritySafeCritical] // auto-generated
2753 [ResourceExposure(ResourceScope.None)]
2754 [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
2757 if (m_cache.IsNull())
2759 IntPtr newgcHandle = new RuntimeTypeHandle(this).GetGCHandle(GCHandleType.WeakTrackResurrection);
2760 IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0);
2761 // Leak the handle if the type is collectible. It will be reclaimed when
2762 // the type goes away.
2763 if (!gcHandle.IsNull() && !IsCollectible())
2764 GCHandle.InternalFree(newgcHandle);
2767 RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
2770 cache = new RuntimeTypeCache(this);
2771 RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache;
2772 if (existingCache != null)
2773 cache = existingCache;
2776 Contract.Assert(cache != null);
2781 internal bool IsSpecialSerializableType()
2783 RuntimeType rt = this;
2786 // In all sane cases we only need to compare the direct level base type with
2787 // System.Enum and System.MulticastDelegate. However, a generic argument can
2788 // have a base type constraint that is Delegate or even a real delegate type.
2789 // Let's maintain compatibility and return true for them.
2790 if (rt == RuntimeType.DelegateType || rt == RuntimeType.EnumType)
2793 rt = rt.GetBaseType();
2794 } while (rt != null);
2799 private string GetDefaultMemberName()
2801 return Cache.GetDefaultMemberName();
2804 #if !FEATURE_CORECLR
2805 internal RuntimeConstructorInfo GetSerializationCtor()
2807 return Cache.GetSerializationCtor();
2813 #region Type Overrides
2815 #region Get XXXInfo Candidates
2816 private ListBuilder<MethodInfo> GetMethodCandidates(
2817 String name, BindingFlags bindingAttr, CallingConventions callConv,
2818 Type[] types, bool allowPrefixLookup)
2820 bool prefixLookup, ignoreCase;
2821 MemberListType listType;
2822 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2825 RuntimeMethodInfo[] cache = GetMethodsByName (name, bindingAttr, ignoreCase, this);
2827 RuntimeMethodInfo[] cache = Cache.GetMethodList(listType, name);
2829 ListBuilder<MethodInfo> candidates = new ListBuilder<MethodInfo>(cache.Length);
2830 for (int i = 0; i < cache.Length; i++)
2832 RuntimeMethodInfo methodInfo = cache[i];
2833 if (FilterApplyMethodInfo(methodInfo, bindingAttr, callConv, types) &&
2834 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase)))
2836 candidates.Add(methodInfo);
2843 private ListBuilder<ConstructorInfo> GetConstructorCandidates(
2844 string name, BindingFlags bindingAttr, CallingConventions callConv,
2845 Type[] types, bool allowPrefixLookup)
2847 bool prefixLookup, ignoreCase;
2848 MemberListType listType;
2849 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2852 if (name != null && name != ConstructorInfo.ConstructorName && name != ConstructorInfo.TypeConstructorName)
2853 return new ListBuilder<ConstructorInfo> (0);
2854 RuntimeConstructorInfo[] cache = GetConstructors_internal (bindingAttr, this);
2856 RuntimeConstructorInfo[] cache = Cache.GetConstructorList(listType, name);
2858 ListBuilder<ConstructorInfo> candidates = new ListBuilder<ConstructorInfo>(cache.Length);
2859 for (int i = 0; i < cache.Length; i++)
2861 RuntimeConstructorInfo constructorInfo = cache[i];
2862 if (FilterApplyConstructorInfo(constructorInfo, bindingAttr, callConv, types) &&
2863 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase)))
2865 candidates.Add(constructorInfo);
2873 private ListBuilder<PropertyInfo> GetPropertyCandidates(
2874 String name, BindingFlags bindingAttr, Type[] types, bool allowPrefixLookup)
2876 bool prefixLookup, ignoreCase;
2877 MemberListType listType;
2878 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2881 RuntimePropertyInfo[] cache = GetPropertiesByName (name, bindingAttr, ignoreCase, this);
2883 #if FEATURE_LEGACYNETCF
2884 // Dev11 466969 quirk
2885 IReadOnlyList<RuntimePropertyInfo> ambiguousProperties = null;
2886 RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name, out ambiguousProperties);
2888 RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name);
2891 bindingAttr ^= BindingFlags.DeclaredOnly;
2893 ListBuilder<PropertyInfo> candidates = new ListBuilder<PropertyInfo>(cache.Length);
2894 for (int i = 0; i < cache.Length; i++)
2896 RuntimePropertyInfo propertyInfo = cache[i];
2897 if ((bindingAttr & propertyInfo.BindingFlags) == propertyInfo.BindingFlags &&
2898 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(propertyInfo, name, ignoreCase)) &&
2899 (types == null || (propertyInfo.GetIndexParameters().Length == types.Length)))
2901 candidates.Add(propertyInfo);
2905 #if FEATURE_LEGACYNETCF
2906 // Dev11 466969 quirk
2907 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 &&
2908 candidates.Count > 1 &&
2909 ambiguousProperties != null &&
2910 ambiguousProperties.Count > 0)
2912 return PruneAmbiguousProperties(candidates, ambiguousProperties);
2919 #if FEATURE_LEGACYNETCF
2920 private ListBuilder<PropertyInfo> PruneAmbiguousProperties(ListBuilder<PropertyInfo> candidates, IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
2922 Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
2923 Contract.Assert(candidates.Count > 1);
2924 Contract.Assert(ambiguousProperties != null && ambiguousProperties.Count > 0);
2926 ListBuilder<PropertyInfo> newCandidates = candidates;
2928 // Dev11 466969 quirk
2929 // NetCF reflection will differentiate properties by sig and by accessibility.
2930 // Consider the following:
2934 // public int Prop { get; set; }
2937 // class FooDerived : FooBase
2939 // private int Prop { get; set; }
2942 // In Mango one can reflect on FooDerived for property "Prop" with *Public*
2943 // binding flags and get an answer. On desktop CLR/CoreCLR you get back null
2944 // since FooBase.Prop is considered a duplicate and thus removed from the
2945 // list of candidate properties. To make this distinction the method
2946 // RuntimePropertyInfo.HasMatchingAccessibility() was added.
2948 // There is a wrinkle here though, when reflecting on FooDerived for
2949 // property "Prop" with Public and NonPublic binding flags the answer
2950 // will always be the most-derived type, so FooDerived in this example.
2951 // The purpose of PruneAmbiguousProperties() is to apply this invariant.
2954 int countRemoved = 0;
2956 lock (ambiguousProperties)
2958 for (int outerIndex = 0; outerIndex < ambiguousProperties.Count; ++outerIndex)
2960 for (int innerIndex = 0; innerIndex < candidates.Count; ++innerIndex)
2962 if (candidates[innerIndex] != null &&
2963 candidates[innerIndex] == ambiguousProperties[outerIndex])
2965 candidates[innerIndex] = null;
2972 // should have only gone down this code path because we knew
2973 // that at least one ambiguous property needed to be pruned.
2974 Contract.Assert(countRemoved > 0);
2976 if (countRemoved > 0)
2978 newCandidates = new ListBuilder<PropertyInfo>(candidates.Count - countRemoved);
2979 for (int index = 0; index < candidates.Count; ++index)
2981 if (candidates[index] != null)
2982 newCandidates.Add(candidates[index]);
2985 Contract.Assert(newCandidates.Count == (candidates.Count - countRemoved));
2988 return newCandidates;
2992 private ListBuilder<EventInfo> GetEventCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
2994 bool prefixLookup, ignoreCase;
2995 MemberListType listType;
2996 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2999 RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, this);
3001 RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3003 bindingAttr ^= BindingFlags.DeclaredOnly;
3005 ListBuilder<EventInfo> candidates = new ListBuilder<EventInfo>(cache.Length);
3006 for (int i = 0; i < cache.Length; i++)
3008 RuntimeEventInfo eventInfo = cache[i];
3009 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags &&
3010 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
3012 candidates.Add(eventInfo);
3019 private ListBuilder<FieldInfo> GetFieldCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
3021 bool prefixLookup, ignoreCase;
3022 MemberListType listType;
3023 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3026 RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, this);
3028 RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3030 bindingAttr ^= BindingFlags.DeclaredOnly;
3032 ListBuilder<FieldInfo> candidates = new ListBuilder<FieldInfo>(cache.Length);
3033 for (int i = 0; i < cache.Length; i++)
3035 RuntimeFieldInfo fieldInfo = cache[i];
3036 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
3037 (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
3039 candidates.Add(fieldInfo);
3046 private ListBuilder<Type> GetNestedTypeCandidates(String fullname, BindingFlags bindingAttr, bool allowPrefixLookup)
3048 bool prefixLookup, ignoreCase;
3049 bindingAttr &= ~BindingFlags.Static;
3051 MemberListType listType;
3052 SplitName(fullname, out name, out ns);
3053 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3056 RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr);
3058 RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3060 ListBuilder<Type> candidates = new ListBuilder<Type>(cache.Length);
3061 for (int i = 0; i < cache.Length; i++)
3063 RuntimeType nestedClass = cache[i];
3064 if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
3066 candidates.Add(nestedClass);
3075 #region Get All XXXInfos
3076 public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
3078 return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
3081 [System.Runtime.InteropServices.ComVisible(true)]
3082 public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
3084 return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
3087 public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
3089 return GetPropertyCandidates(null, bindingAttr, null, false).ToArray();
3092 public override EventInfo[] GetEvents(BindingFlags bindingAttr)
3094 return GetEventCandidates(null, bindingAttr, false).ToArray();
3097 public override FieldInfo[] GetFields(BindingFlags bindingAttr)
3099 return GetFieldCandidates(null, bindingAttr, false).ToArray();
3102 [System.Security.SecuritySafeCritical] // auto-generated
3103 public override Type[] GetInterfaces()
3105 RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
3106 Type[] interfaces = new Type[candidates.Length];
3107 for (int i = 0; i < candidates.Length; i++)
3108 JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
3113 public override Type[] GetNestedTypes(BindingFlags bindingAttr)
3115 return GetNestedTypeCandidates(null, bindingAttr, false).ToArray();
3118 public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
3120 ListBuilder<MethodInfo> methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
3121 ListBuilder<ConstructorInfo> constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false);
3122 ListBuilder<PropertyInfo> properties = GetPropertyCandidates(null, bindingAttr, null, false);
3123 ListBuilder<EventInfo> events = GetEventCandidates(null, bindingAttr, false);
3124 ListBuilder<FieldInfo> fields = GetFieldCandidates(null, bindingAttr, false);
3125 ListBuilder<Type> nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false);
3126 // Interfaces are excluded from the result of GetMembers
3128 MemberInfo[] members = new MemberInfo[
3130 constructors.Count +
3137 methods.CopyTo(members, i); i += methods.Count;
3138 constructors.CopyTo(members, i); i += constructors.Count;
3139 properties.CopyTo(members, i); i += properties.Count;
3140 events.CopyTo(members, i); i += events.Count;
3141 fields.CopyTo(members, i); i += fields.Count;
3142 nestedTypes.CopyTo(members, i); i += nestedTypes.Count;
3143 Contract.Assert(i == members.Length);
3148 [System.Security.SecuritySafeCritical] // auto-generated
3149 public override InterfaceMapping GetInterfaceMap(Type ifaceType)
3151 if (IsGenericParameter)
3152 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
3154 if ((object)ifaceType == null)
3155 throw new ArgumentNullException("ifaceType");
3156 Contract.EndContractBlock();
3158 RuntimeType ifaceRtType = ifaceType as RuntimeType;
3160 if (ifaceRtType == null)
3161 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
3163 RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
3165 GetTypeHandleInternal().VerifyInterfaceIsImplemented(ifaceRtTypeHandle);
3166 Contract.Assert(ifaceType.IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
3167 Contract.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
3169 // SZArrays implement the methods on IList`1, IEnumerable`1, and ICollection`1 with
3170 // SZArrayHelper and some runtime magic. We don't have accurate interface maps for them.
3171 if (IsSzArray && ifaceType.IsGenericType)
3172 throw new ArgumentException(Environment.GetResourceString("Argument_ArrayGetInterfaceMap"));
3174 int ifaceInstanceMethodCount = RuntimeTypeHandle.GetNumVirtuals(ifaceRtType);
3176 InterfaceMapping im;
3177 im.InterfaceType = ifaceType;
3178 im.TargetType = this;
3179 im.InterfaceMethods = new MethodInfo[ifaceInstanceMethodCount];
3180 im.TargetMethods = new MethodInfo[ifaceInstanceMethodCount];
3182 for (int i = 0; i < ifaceInstanceMethodCount; i++)
3184 RuntimeMethodHandleInternal ifaceRtMethodHandle = RuntimeTypeHandle.GetMethodAt(ifaceRtType, i);
3186 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3187 MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtType, ifaceRtMethodHandle);
3188 Contract.Assert(ifaceMethodBase is RuntimeMethodInfo);
3189 im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase;
3191 // If the slot is -1, then virtual stub dispatch is active.
3192 int slot = GetTypeHandleInternal().GetInterfaceMethodImplementationSlot(ifaceRtTypeHandle, ifaceRtMethodHandle);
3194 if (slot == -1) continue;
3196 RuntimeMethodHandleInternal classRtMethodHandle = RuntimeTypeHandle.GetMethodAt(this, slot);
3198 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3199 MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(this, classRtMethodHandle);
3200 // a class may not implement all the methods of an interface (abstract class) so null is a valid value
3201 Contract.Assert(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
3202 im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase;
3210 #region Find XXXInfo
3211 protected override MethodInfo GetMethodImpl(
3212 String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv,
3213 Type[] types, ParameterModifier[] modifiers)
3215 ListBuilder<MethodInfo> candidates = GetMethodCandidates(name, bindingAttr, callConv, types, false);
3216 if (candidates.Count == 0)
3219 if (types == null || types.Length == 0)
3221 MethodInfo firstCandidate = candidates[0];
3223 if (candidates.Count == 1)
3225 return firstCandidate;
3227 else if (types == null)
3229 for (int j = 1; j < candidates.Count; j++)
3231 MethodInfo methodInfo = candidates[j];
3232 if (!System.DefaultBinder.CompareMethodSigAndName(methodInfo, firstCandidate))
3234 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3238 // All the methods have the exact same name and sig so return the most derived one.
3239 return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo;
3244 binder = DefaultBinder;
3246 return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;
3250 protected override ConstructorInfo GetConstructorImpl(
3251 BindingFlags bindingAttr, Binder binder, CallingConventions callConvention,
3252 Type[] types, ParameterModifier[] modifiers)
3254 ListBuilder<ConstructorInfo> candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false);
3256 if (candidates.Count == 0)
3259 if (types.Length == 0 && candidates.Count == 1)
3261 ConstructorInfo firstCandidate = candidates[0];
3263 ParameterInfo[] parameters = firstCandidate.GetParametersNoCopy();
3264 if (parameters == null || parameters.Length == 0)
3266 return firstCandidate;
3270 if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3271 return System.DefaultBinder.ExactBinding(candidates.ToArray(), types, modifiers) as ConstructorInfo;
3274 binder = DefaultBinder;
3276 return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo;
3280 protected override PropertyInfo GetPropertyImpl(
3281 String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
3283 if (name == null) throw new ArgumentNullException();
3284 Contract.EndContractBlock();
3286 ListBuilder<PropertyInfo> candidates = GetPropertyCandidates(name, bindingAttr, types, false);
3288 if (candidates.Count == 0)
3291 if (types == null || types.Length == 0)
3294 if (candidates.Count == 1)
3296 PropertyInfo firstCandidate = candidates[0];
3298 if ((object)returnType != null && !returnType.IsEquivalentTo(firstCandidate.PropertyType))
3301 return firstCandidate;
3305 if ((object)returnType == null)
3306 // if we are here we have no args or property type to select over and we have more than one property with that name
3307 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3311 if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3312 return System.DefaultBinder.ExactPropertyBinding(candidates.ToArray(), returnType, types, modifiers);
3315 binder = DefaultBinder;
3317 return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
3320 public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
3322 if (name == null) throw new ArgumentNullException();
3323 Contract.EndContractBlock();
3326 MemberListType listType;
3327 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3330 RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, this);
3332 RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3334 EventInfo match = null;
3336 bindingAttr ^= BindingFlags.DeclaredOnly;
3338 for (int i = 0; i < cache.Length; i++)
3340 RuntimeEventInfo eventInfo = cache[i];
3341 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags)
3344 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3353 public override FieldInfo GetField(String name, BindingFlags bindingAttr)
3355 if (name == null) throw new ArgumentNullException();
3356 Contract.EndContractBlock();
3359 MemberListType listType;
3360 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3363 RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, this);
3365 RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3367 FieldInfo match = null;
3369 bindingAttr ^= BindingFlags.DeclaredOnly;
3370 bool multipleStaticFieldMatches = false;
3372 for (int i = 0; i < cache.Length; i++)
3374 RuntimeFieldInfo fieldInfo = cache[i];
3375 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
3379 if (Object.ReferenceEquals(fieldInfo.DeclaringType, match.DeclaringType))
3380 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3382 if ((match.DeclaringType.IsInterface == true) && (fieldInfo.DeclaringType.IsInterface == true))
3383 multipleStaticFieldMatches = true;
3386 if (match == null || fieldInfo.DeclaringType.IsSubclassOf(match.DeclaringType) || match.DeclaringType.IsInterface)
3391 if (multipleStaticFieldMatches && match.DeclaringType.IsInterface)
3392 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3397 public override Type GetInterface(String fullname, bool ignoreCase)
3399 if (fullname == null) throw new ArgumentNullException();
3400 Contract.EndContractBlock();
3402 BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic;
3404 bindingAttr &= ~BindingFlags.Static;
3407 bindingAttr |= BindingFlags.IgnoreCase;
3410 MemberListType listType;
3411 SplitName(fullname, out name, out ns);
3412 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3415 List<RuntimeType> list = null;
3416 foreach (RuntimeType t in GetInterfaces ()) {
3421 list = new List<RuntimeType> (2);
3429 var cache = list.ToArray ();
3431 RuntimeType[] cache = Cache.GetInterfaceList(listType, name);
3433 RuntimeType match = null;
3435 for (int i = 0; i < cache.Length; i++)
3437 RuntimeType iface = cache[i];
3438 if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
3441 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3450 public override Type GetNestedType(String fullname, BindingFlags bindingAttr)
3452 if (fullname == null) throw new ArgumentNullException();
3453 Contract.EndContractBlock();
3456 bindingAttr &= ~BindingFlags.Static;
3458 MemberListType listType;
3459 SplitName(fullname, out name, out ns);
3460 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3462 RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr);
3464 RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3466 RuntimeType match = null;
3468 for (int i = 0; i < cache.Length; i++)
3470 RuntimeType nestedType = cache[i];
3471 if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
3474 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3483 public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
3485 if (name == null) throw new ArgumentNullException();
3486 Contract.EndContractBlock();
3488 ListBuilder<MethodInfo> methods = new ListBuilder<MethodInfo>();
3489 ListBuilder<ConstructorInfo> constructors = new ListBuilder<ConstructorInfo>();
3490 ListBuilder<PropertyInfo> properties = new ListBuilder<PropertyInfo>();
3491 ListBuilder<EventInfo> events = new ListBuilder<EventInfo>();
3492 ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>();
3493 ListBuilder<Type> nestedTypes = new ListBuilder<Type>();
3498 if ((type & MemberTypes.Method) != 0)
3500 methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, true);
3501 if (type == MemberTypes.Method)
3502 return methods.ToArray();
3503 totalCount += methods.Count;
3507 if ((type & MemberTypes.Constructor) != 0)
3509 constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true);
3510 if (type == MemberTypes.Constructor)
3511 return constructors.ToArray();
3512 totalCount += constructors.Count;
3516 if ((type & MemberTypes.Property) != 0)
3518 properties = GetPropertyCandidates(name, bindingAttr, null, true);
3519 if (type == MemberTypes.Property)
3520 return properties.ToArray();
3521 totalCount += properties.Count;
3525 if ((type & MemberTypes.Event) != 0)
3527 events = GetEventCandidates(name, bindingAttr, true);
3528 if (type == MemberTypes.Event)
3529 return events.ToArray();
3530 totalCount += events.Count;
3534 if ((type & MemberTypes.Field) != 0)
3536 fields = GetFieldCandidates(name, bindingAttr, true);
3537 if (type == MemberTypes.Field)
3538 return fields.ToArray();
3539 totalCount += fields.Count;
3543 if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
3545 nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);
3546 if (type == MemberTypes.NestedType || type == MemberTypes.TypeInfo)
3547 return nestedTypes.ToArray();
3548 totalCount += nestedTypes.Count;
3551 MemberInfo[] compressMembers = (type == (MemberTypes.Method | MemberTypes.Constructor)) ?
3552 new MethodBase[totalCount] : new MemberInfo[totalCount];
3555 methods.CopyTo(compressMembers, i); i += methods.Count;
3556 constructors.CopyTo(compressMembers, i); i += constructors.Count;
3557 properties.CopyTo(compressMembers, i); i += properties.Count;
3558 events.CopyTo(compressMembers, i); i += events.Count;
3559 fields.CopyTo(compressMembers, i); i += fields.Count;
3560 nestedTypes.CopyTo(compressMembers, i); i += nestedTypes.Count;
3561 Contract.Assert(i == compressMembers.Length);
3563 return compressMembers;
3569 public override Module Module
3573 return GetRuntimeModule();
3577 internal RuntimeModule GetRuntimeModule()
3579 return RuntimeTypeHandle.GetModule(this);
3582 public override Assembly Assembly
3586 return GetRuntimeAssembly();
3590 internal RuntimeAssembly GetRuntimeAssembly()
3592 return RuntimeTypeHandle.GetAssembly(this);
3595 public override RuntimeTypeHandle TypeHandle
3599 return new RuntimeTypeHandle(this);
3603 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
3604 internal sealed override RuntimeTypeHandle GetTypeHandleInternal()
3606 return new RuntimeTypeHandle(this);
3609 [System.Security.SecuritySafeCritical]
3610 internal bool IsCollectible()
3612 return RuntimeTypeHandle.IsCollectible(GetTypeHandleInternal());
3615 [System.Security.SecuritySafeCritical] // auto-generated
3616 protected override TypeCode GetTypeCodeImpl()
3618 TypeCode typeCode = Cache.TypeCode;
3620 if (typeCode != TypeCode.Empty)
3623 CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this);
3624 switch (corElementType)
3626 case CorElementType.Boolean:
3627 typeCode = TypeCode.Boolean; break;
3628 case CorElementType.Char:
3629 typeCode = TypeCode.Char; break;
3630 case CorElementType.I1:
3631 typeCode = TypeCode.SByte; break;
3632 case CorElementType.U1:
3633 typeCode = TypeCode.Byte; break;
3634 case CorElementType.I2:
3635 typeCode = TypeCode.Int16; break;
3636 case CorElementType.U2:
3637 typeCode = TypeCode.UInt16; break;
3638 case CorElementType.I4:
3639 typeCode = TypeCode.Int32; break;
3640 case CorElementType.U4:
3641 typeCode = TypeCode.UInt32; break;
3642 case CorElementType.I8:
3643 typeCode = TypeCode.Int64; break;
3644 case CorElementType.U8:
3645 typeCode = TypeCode.UInt64; break;
3646 case CorElementType.R4:
3647 typeCode = TypeCode.Single; break;
3648 case CorElementType.R8:
3649 typeCode = TypeCode.Double; break;
3650 case CorElementType.String:
3651 typeCode = TypeCode.String; break;
3652 case CorElementType.ValueType:
3653 if (this == Convert.ConvertTypes[(int)TypeCode.Decimal])
3654 typeCode = TypeCode.Decimal;
3655 else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
3656 typeCode = TypeCode.DateTime;
3657 else if (this.IsEnum)
3658 typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
3660 typeCode = TypeCode.Object;
3663 if (this == Convert.ConvertTypes[(int)TypeCode.DBNull])
3664 typeCode = TypeCode.DBNull;
3665 else if (this == Convert.ConvertTypes[(int)TypeCode.String])
3666 typeCode = TypeCode.String;
3668 typeCode = TypeCode.Object;
3672 Cache.TypeCode = typeCode;
3677 public override MethodBase DeclaringMethod
3681 if (!IsGenericParameter)
3682 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
3683 Contract.EndContractBlock();
3685 IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this);
3687 if (declaringMethod == null)
3690 return GetMethodBase(RuntimeMethodHandle.GetDeclaringType(declaringMethod), declaringMethod);
3697 [System.Security.SecuritySafeCritical] // auto-generated
3698 public override bool IsInstanceOfType(Object o)
3700 return RuntimeTypeHandle.IsInstanceOfType(this, o);
3703 [System.Runtime.InteropServices.ComVisible(true)]
3705 public override bool IsSubclassOf(Type type)
3707 if ((object)type == null)
3708 throw new ArgumentNullException("type");
3709 Contract.EndContractBlock();
3710 RuntimeType rtType = type as RuntimeType;
3714 RuntimeType baseType = GetBaseType();
3716 while (baseType != null)
3718 if (baseType == rtType)
3721 baseType = baseType.GetBaseType();
3724 // pretty much everything is a subclass of object, even interfaces
3725 // notice that interfaces are really odd because they do not have a BaseType
3726 // yet IsSubclassOf(typeof(object)) returns true
3727 if (rtType == RuntimeType.ObjectType && rtType != this)
3733 public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
3734 if(typeInfo==null) return false;
3735 return IsAssignableFrom(typeInfo.AsType());
3738 public override bool IsAssignableFrom(Type c)
3740 if ((object)c == null)
3743 if (Object.ReferenceEquals(c, this))
3746 RuntimeType fromType = c.UnderlyingSystemType as RuntimeType;
3748 // For runtime type, let the VM decide.
3749 if (fromType != null)
3751 // both this and c (or their underlying system types) are runtime types
3752 return RuntimeTypeHandle.CanCastTo(fromType, this);
3754 #if !FULL_AOT_RUNTIME
3755 // Special case for TypeBuilder to be backward-compatible.
3756 if (c is System.Reflection.Emit.TypeBuilder)
3758 // If c is a subclass of this class, then c can be cast to this type.
3759 if (c.IsSubclassOf(this))
3762 if (this.IsInterface)
3764 return c.ImplementInterface(this);
3766 else if (this.IsGenericParameter)
3768 Type[] constraints = GetGenericParameterConstraints();
3769 for (int i = 0; i < constraints.Length; i++)
3770 if (!constraints[i].IsAssignableFrom(c))
3777 // For anything else we return false.
3781 #if !FEATURE_CORECLR
3782 // Reflexive, symmetric, transitive.
3783 public override bool IsEquivalentTo(Type other)
3785 RuntimeType otherRtType = other as RuntimeType;
3786 if ((object)otherRtType == null)
3789 if (otherRtType == this)
3792 // It's not worth trying to perform further checks in managed
3793 // as they would lead to FCalls anyway.
3794 return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);
3796 #endif // FEATURE_CORECLR
3798 public override Type BaseType
3802 return GetBaseType();
3806 private RuntimeType GetBaseType()
3811 if (RuntimeTypeHandle.IsGenericVariable(this))
3813 Type[] constraints = GetGenericParameterConstraints();
3815 RuntimeType baseType = RuntimeType.ObjectType;
3817 for (int i = 0; i < constraints.Length; i++)
3819 RuntimeType constraint = (RuntimeType)constraints[i];
3821 if (constraint.IsInterface)
3824 if (constraint.IsGenericParameter)
3826 GenericParameterAttributes special;
3827 special = constraint.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3829 if ((special & GenericParameterAttributes.ReferenceTypeConstraint) == 0 &&
3830 (special & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
3834 baseType = constraint;
3837 if (baseType == RuntimeType.ObjectType)
3839 GenericParameterAttributes special;
3840 special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3841 if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
3842 baseType = RuntimeType.ValueType;
3848 return RuntimeTypeHandle.GetBaseType(this);
3851 public override Type UnderlyingSystemType
3861 public override String FullName
3865 return GetCachedName(TypeNameKind.FullName);
3869 public override String AssemblyQualifiedName
3873 string fullname = FullName;
3875 // FullName is null if this type contains generic parameters but is not a generic type definition.
3876 if (fullname == null)
3879 return Assembly.CreateQualifiedName(this.Assembly.FullName, fullname);
3883 public override String Namespace
3887 string ns = Cache.GetNameSpace();
3889 if (ns == null || ns.Length == 0)
3898 [System.Security.SecuritySafeCritical] // auto-generated
3899 protected override TypeAttributes GetAttributeFlagsImpl()
3901 return RuntimeTypeHandle.GetAttributes(this);
3904 public override Guid GUID
3906 [System.Security.SecuritySafeCritical] // auto-generated
3909 Guid result = new Guid ();
3910 GetGUID(ref result);
3915 [System.Security.SecurityCritical] // auto-generated
3916 [ResourceExposure(ResourceScope.None)]
3917 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3918 private extern void GetGUID(ref Guid result);
3920 [System.Security.SecuritySafeCritical] // auto-generated
3921 protected override bool IsContextfulImpl()
3923 return RuntimeTypeHandle.IsContextful(this);
3927 protected override bool IsMarshalByRefImpl()
3929 return GetTypeHandleInternal().IsMarshalByRef();
3933 protected override bool IsByRefImpl()
3935 return RuntimeTypeHandle.IsByRef(this);
3938 protected override bool IsPrimitiveImpl()
3940 return RuntimeTypeHandle.IsPrimitive(this);
3943 protected override bool IsPointerImpl()
3945 return RuntimeTypeHandle.IsPointer(this);
3948 [System.Security.SecuritySafeCritical] // auto-generated
3949 protected override bool IsCOMObjectImpl()
3951 return RuntimeTypeHandle.IsComObject(this, false);
3954 #if FEATURE_COMINTEROP
3955 [SecuritySafeCritical]
3956 internal override bool IsWindowsRuntimeObjectImpl()
3958 return IsWindowsRuntimeObjectType(this);
3961 [SecuritySafeCritical]
3962 internal override bool IsExportedToWindowsRuntimeImpl()
3964 return IsTypeExportedToWindowsRuntime(this);
3967 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3969 private static extern bool IsWindowsRuntimeObjectType(RuntimeType type);
3971 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3973 private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type);
3975 #endif // FEATURE_COMINTEROP
3977 [System.Security.SecuritySafeCritical] // auto-generated
3978 internal override bool HasProxyAttributeImpl()
3980 return RuntimeTypeHandle.HasProxyAttribute(this);
3983 internal bool IsDelegate()
3985 return GetBaseType() == typeof(System.MulticastDelegate);
3988 protected override bool IsValueTypeImpl()
3990 // We need to return true for generic parameters with the ValueType constraint.
3991 // So we cannot use the faster RuntimeTypeHandle.IsValueType because it returns
3992 // false for all generic parameters.
3993 if (this == typeof(ValueType) || this == typeof(Enum))
3996 return IsSubclassOf(typeof(ValueType));
3999 #if !FEATURE_CORECLR
4000 public override bool IsEnum
4004 return GetBaseType() == RuntimeType.EnumType;
4009 protected override bool HasElementTypeImpl()
4011 return RuntimeTypeHandle.HasElementType(this);
4014 public override GenericParameterAttributes GenericParameterAttributes
4016 [System.Security.SecuritySafeCritical] // auto-generated
4019 if (!IsGenericParameter)
4020 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4021 Contract.EndContractBlock();
4024 return GetGenericParameterAttributes ();
4026 GenericParameterAttributes attributes;
4028 RuntimeTypeHandle.GetMetadataImport(this).GetGenericParamProps(MetadataToken, out attributes);
4035 public override bool IsSecurityCritical
4037 get { return new RuntimeTypeHandle(this).IsSecurityCritical(); }
4039 public override bool IsSecuritySafeCritical
4041 get { return new RuntimeTypeHandle(this).IsSecuritySafeCritical(); }
4043 public override bool IsSecurityTransparent
4045 get { return new RuntimeTypeHandle(this).IsSecurityTransparent(); }
4051 internal override bool IsSzArray
4055 return RuntimeTypeHandle.IsSzArray(this);
4059 protected override bool IsArrayImpl()
4061 return RuntimeTypeHandle.IsArray(this);
4064 [System.Security.SecuritySafeCritical] // auto-generated
4065 public override int GetArrayRank()
4068 throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
4070 return RuntimeTypeHandle.GetArrayRank(this);
4073 public override Type GetElementType()
4075 return RuntimeTypeHandle.GetElementType(this);
4080 public override string[] GetEnumNames()
4083 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4084 Contract.EndContractBlock();
4086 String[] ret = Enum.InternalGetNames(this);
4088 // Make a copy since we can't hand out the same array since users can modify them
4089 String[] retVal = new String[ret.Length];
4091 Array.Copy(ret, retVal, ret.Length);
4096 [SecuritySafeCritical]
4097 public override Array GetEnumValues()
4100 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4101 Contract.EndContractBlock();
4103 // Get all of the values
4104 ulong[] values = Enum.InternalGetValues(this);
4106 // Create a generic Array
4107 Array ret = Array.UnsafeCreateInstance(this, values.Length);
4109 for (int i = 0; i < values.Length; i++)
4111 Object val = Enum.ToObject(this, values[i]);
4112 ret.SetValue(val, i);
4118 public override Type GetEnumUnderlyingType()
4121 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4122 Contract.EndContractBlock();
4124 return Enum.InternalGetUnderlyingType(this);
4127 public override bool IsEnumDefined(object value)
4130 throw new ArgumentNullException("value");
4131 Contract.EndContractBlock();
4133 // Check if both of them are of the same type
4134 RuntimeType valueType = (RuntimeType)value.GetType();
4136 // If the value is an Enum then we need to extract the underlying value from it
4137 if (valueType.IsEnum)
4139 if (!valueType.IsEquivalentTo(this))
4140 throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
4142 valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
4145 // If a string is passed in
4146 if (valueType == RuntimeType.StringType)
4148 // Get all of the Fields, calling GetHashEntry directly to avoid copying
4149 string[] names = Enum.InternalGetNames(this);
4150 if (Array.IndexOf(names, value) >= 0)
4156 // If an enum or integer value is passed in
4157 if (Type.IsIntegerType(valueType))
4159 RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
4160 if (underlyingType != valueType)
4161 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
4163 ulong[] ulValues = Enum.InternalGetValues(this);
4164 ulong ulValue = Enum.ToUInt64(value);
4166 return (Array.BinarySearch(ulValues, ulValue) >= 0);
4168 else if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
4170 // if at this point the value type is not an integer type, then its type doesn't match the enum type
4171 // NetCF used to throw an argument exception in this case
4172 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), GetEnumUnderlyingType()));
4176 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
4180 public override string GetEnumName(object value)
4183 throw new ArgumentNullException("value");
4184 Contract.EndContractBlock();
4186 Type valueType = value.GetType();
4188 if (!(valueType.IsEnum || IsIntegerType(valueType)))
4189 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
4191 ulong[] ulValues = Enum.InternalGetValues(this);
4192 ulong ulValue = Enum.ToUInt64(value);
4193 int index = Array.BinarySearch(ulValues, ulValue);
4197 string[] names = Enum.InternalGetNames(this);
4198 return names[index];
4207 internal RuntimeType[] GetGenericArgumentsInternal()
4210 return (RuntimeType[]) GetGenericArgumentsInternal (true);
4212 return GetRootElementType().GetTypeHandleInternal().GetInstantiationInternal();
4216 public override Type[] GetGenericArguments()
4219 Type[] types = GetGenericArgumentsInternal (false);
4221 Type[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiationPublic();
4225 types = EmptyArray<Type>.Value;
4230 [System.Security.SecuritySafeCritical] // auto-generated
4231 public override Type MakeGenericType(Type[] instantiation)
4233 if (instantiation == null)
4234 throw new ArgumentNullException("instantiation");
4235 Contract.EndContractBlock();
4237 RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length];
4239 if (!IsGenericTypeDefinition)
4240 throw new InvalidOperationException(
4241 Environment.GetResourceString("Arg_NotGenericTypeDefinition", this));
4243 if (GetGenericArguments().Length != instantiation.Length)
4244 throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), "instantiation");
4246 for (int i = 0; i < instantiation.Length; i ++)
4248 Type instantiationElem = instantiation[i];
4249 if (instantiationElem == null)
4250 throw new ArgumentNullException();
4252 RuntimeType rtInstantiationElem = instantiationElem as RuntimeType;
4254 if (rtInstantiationElem == null)
4256 Type[] instantiationCopy = new Type[instantiation.Length];
4257 for (int iCopy = 0; iCopy < instantiation.Length; iCopy++)
4258 instantiationCopy[iCopy] = instantiation[iCopy];
4259 instantiation = instantiationCopy;
4260 return System.Reflection.Emit.TypeBuilderInstantiation.MakeGenericType(this, instantiation);
4263 instantiationRuntimeType[i] = rtInstantiationElem;
4266 RuntimeType[] genericParameters = GetGenericArgumentsInternal();
4268 SanityCheckGenericArguments(instantiationRuntimeType, genericParameters);
4272 ret = MakeGenericType (this, instantiationRuntimeType);
4274 throw new TypeLoadException ();
4278 ret = new RuntimeTypeHandle(this).Instantiate(instantiationRuntimeType);
4280 catch (TypeLoadException e)
4282 ValidateGenericArguments(this, instantiationRuntimeType, e);
4289 public override bool IsGenericTypeDefinition
4291 get { return RuntimeTypeHandle.IsGenericTypeDefinition(this); }
4294 public override bool IsGenericParameter
4296 get { return RuntimeTypeHandle.IsGenericVariable(this); }
4299 public override int GenericParameterPosition
4303 if (!IsGenericParameter)
4304 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4305 Contract.EndContractBlock();
4307 return GetGenericParameterPosition ();
4309 return new RuntimeTypeHandle(this).GetGenericVariableIndex();
4314 public override Type GetGenericTypeDefinition()
4317 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotGenericType"));
4318 Contract.EndContractBlock();
4320 return RuntimeTypeHandle.GetGenericTypeDefinition(this);
4323 public override bool IsGenericType
4325 get { return RuntimeTypeHandle.HasInstantiation(this); }
4328 public override bool IsConstructedGenericType
4330 get { return IsGenericType && !IsGenericTypeDefinition; }
4333 public override bool ContainsGenericParameters
4335 get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
4338 public override Type[] GetGenericParameterConstraints()
4340 if (!IsGenericParameter)
4341 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4342 Contract.EndContractBlock();
4344 Type[] constraints = new RuntimeTypeHandle(this).GetConstraints();
4346 if (constraints == null)
4347 constraints = EmptyArray<Type>.Value;
4355 [System.Security.SecuritySafeCritical] // auto-generated
4356 public override Type MakePointerType() { return new RuntimeTypeHandle(this).MakePointer(); }
4357 public override Type MakeByRefType() { return new RuntimeTypeHandle(this).MakeByRef(); }
4358 public override Type MakeArrayType() { return new RuntimeTypeHandle(this).MakeSZArray(); }
4359 public override Type MakeArrayType(int rank)
4362 throw new IndexOutOfRangeException();
4363 Contract.EndContractBlock();
4365 return new RuntimeTypeHandle(this).MakeArray(rank);
4367 public override StructLayoutAttribute StructLayoutAttribute
4369 [System.Security.SecuritySafeCritical] // overrides transparent public member
4372 return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
4377 #region Invoke Member
4378 private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
4379 private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
4380 private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
4381 private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
4382 private const BindingFlags BinderSetInvokeProperty = BindingFlags.InvokeMethod | BindingFlags.SetProperty;
4383 private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
4384 private const BindingFlags BinderSetInvokeField = BindingFlags.SetField | BindingFlags.InvokeMethod;
4385 private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
4386 private const BindingFlags ClassicBindingMask =
4387 BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
4388 BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
4389 private static RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
4391 [System.Security.SecurityCritical] // auto-generated
4392 [ResourceExposure(ResourceScope.None)]
4393 [MethodImplAttribute(MethodImplOptions.InternalCall)]
4394 static private extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
4396 [System.Security.SecurityCritical] // auto-generated
4397 [ResourceExposure(ResourceScope.None)]
4398 [MethodImplAttribute(MethodImplOptions.InternalCall)]
4399 static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange);
4401 [System.Security.SecuritySafeCritical] // auto-generated
4402 internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
4404 // this method is used by invocation in reflection to check whether a value can be assigned to type.
4405 if (IsInstanceOfType(value))
4407 // Since this cannot be a generic parameter, we use RuntimeTypeHandle.IsValueType here
4408 // because it is faster than RuntimeType.IsValueType
4409 Contract.Assert(!IsGenericParameter);
4413 #if FEATURE_REMOTING
4414 // For the remoting objects Object.GetType goes through proxy. Avoid the proxy call and just get
4415 // the type directly. It is necessary to support proxies that do not handle GetType.
4416 RealProxy realProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(value);
4418 if (realProxy != null)
4420 type = realProxy.GetProxiedType();
4424 type = value.GetType();
4427 type = value.GetType();
4430 if (!Object.ReferenceEquals(type, this) && RuntimeTypeHandle.IsValueType(this))
4432 // must be an equivalent type, re-box to the target type
4433 return AllocateValueType(this, value, true);
4441 // if this is a ByRef get the element type and check if it's compatible
4442 bool isByRef = IsByRef;
4445 RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4446 if (elementType.IsInstanceOfType(value) || value == null)
4448 // need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
4449 return AllocateValueType(elementType, value, false);
4452 else if (value == null)
4454 else if (this == s_typedRef)
4455 // everything works for a typedref
4458 // check the strange ones courtesy of reflection:
4459 // - implicit cast between primitives
4460 // - enum treated as underlying type
4461 // - IntPtr and System.Reflection.Pointer to pointer types
4462 bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive;
4463 if (needsSpecialCast)
4465 RuntimeType valueType;
4466 Pointer pointer = value as Pointer;
4467 if (pointer != null)
4468 valueType = pointer.GetPointerType();
4470 valueType = (RuntimeType)value.GetType();
4472 if (CanValueSpecialCast(valueType, this))
4474 if (pointer != null)
4475 return pointer.GetPointerValue();
4481 if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
4482 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4484 return TryChangeType(value, binder, culture, needsSpecialCast);
4487 // Factored out of CheckValue to reduce code complexity.
4488 [System.Security.SecurityCritical]
4489 private Object TryChangeType(Object value, Binder binder, CultureInfo culture, bool needsSpecialCast)
4491 if (binder != null && binder != Type.DefaultBinder)
4493 value = binder.ChangeType(value, this, culture);
4494 if (IsInstanceOfType(value))
4496 // if this is a ByRef get the element type and check if it's compatible
4499 RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4500 if (elementType.IsInstanceOfType(value) || value == null)
4501 return AllocateValueType(elementType, value, false);
4503 else if (value == null)
4505 if (needsSpecialCast)
4507 RuntimeType valueType;
4508 Pointer pointer = value as Pointer;
4509 if (pointer != null)
4510 valueType = pointer.GetPointerType();
4512 valueType = (RuntimeType)value.GetType();
4514 if (CanValueSpecialCast(valueType, this))
4516 if (pointer != null)
4517 return pointer.GetPointerValue();
4524 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4527 // GetDefaultMembers
4528 // This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
4529 public override MemberInfo[] GetDefaultMembers()
4531 // See if we have cached the default member name
4532 MemberInfo[] members = null;
4534 String defaultMemberName = GetDefaultMemberName();
4535 if (defaultMemberName != null)
4537 members = GetMember(defaultMemberName);
4540 if (members == null)
4541 members = EmptyArray<MemberInfo>.Value;
4546 #if FEATURE_COMINTEROP
4547 [System.Security.SecuritySafeCritical] // auto-generated
4549 [DebuggerStepThroughAttribute]
4550 [Diagnostics.DebuggerHidden]
4551 public override Object InvokeMember(
4552 String name, BindingFlags bindingFlags, Binder binder, Object target,
4553 Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
4555 if (IsGenericParameter)
4556 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
4557 Contract.EndContractBlock();
4559 #region Preconditions
4560 if ((bindingFlags & InvocationMask) == 0)
4561 // "Must specify binding flags describing the invoke operation required."
4562 throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),"bindingFlags");
4564 // Provide a default binding mask if none is provided
4565 if ((bindingFlags & MemberBindingMask) == 0)
4567 bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
4569 if ((bindingFlags & BindingFlags.CreateInstance) == 0)
4570 bindingFlags |= BindingFlags.Static;
4573 // There must not be more named parameters than provided arguments
4574 if (namedParams != null)
4576 if (providedArgs != null)
4578 if (namedParams.Length > providedArgs.Length)
4579 // "Named parameter array can not be bigger than argument array."
4580 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4584 if (namedParams.Length != 0)
4585 // "Named parameter array can not be bigger than argument array."
4586 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4592 #if FEATURE_COMINTEROP && FEATURE_USE_LCID
4593 if (target != null && target.GetType().IsCOMObject)
4595 #region Preconditions
4596 if ((bindingFlags & ClassicBindingMask) == 0)
4597 throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
4599 if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4600 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4602 if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4603 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4605 if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
4606 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4608 if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
4609 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4611 if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
4612 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4615 #if FEATURE_REMOTING
4616 if(!RemotingServices.IsTransparentProxy(target))
4619 #region Non-TransparentProxy case
4621 throw new ArgumentNullException("name");
4623 bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
4625 // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
4626 int lcid = (culture == null ? 0x0409 : culture.LCID);
4629 throw new NotImplementedException ();
4631 return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
4635 #if FEATURE_REMOTING
4639 throw new NotImplementedException ();
4641 #region TransparentProxy case
4642 return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
4646 #endif // FEATURE_REMOTING
4648 #endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
4651 #region Check that any named paramters are not null
4652 if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
4653 // "Named parameter value must not be null."
4654 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),"namedParams");
4657 int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
4659 #region Get a Binder
4661 binder = DefaultBinder;
4663 bool bDefaultBinder = (binder == DefaultBinder);
4666 #region Delegate to Activator.CreateInstance
4667 if ((bindingFlags & BindingFlags.CreateInstance) != 0)
4669 if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
4670 // "Can not specify both CreateInstance and another access type."
4671 throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),"bindingFlags");
4673 return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
4677 // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
4678 if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
4679 bindingFlags |= BindingFlags.SetProperty;
4683 throw new ArgumentNullException("name");
4685 if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
4687 name = GetDefaultMemberName();
4691 // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
4697 #region GetField or SetField
4698 bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
4699 bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
4701 if (IsGetField || IsSetField)
4703 #region Preconditions
4707 // "Can not specify both Get and Set on a field."
4708 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
4710 if ((bindingFlags & BindingFlags.SetProperty) != 0)
4711 // "Can not specify both GetField and SetProperty."
4712 throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags");
4716 Contract.Assert(IsSetField);
4718 if (providedArgs == null)
4719 throw new ArgumentNullException("providedArgs");
4721 if ((bindingFlags & BindingFlags.GetProperty) != 0)
4722 // "Can not specify both SetField and GetProperty."
4723 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags");
4725 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4726 // "Can not specify Set on a Field and Invoke on a method."
4727 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"bindingFlags");
4731 #region Lookup Field
4732 FieldInfo selFld = null;
4733 FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
4735 Contract.Assert(flds != null);
4737 if (flds.Length == 1)
4741 else if (flds.Length > 0)
4743 selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
4749 #region Invocation on a field
4750 if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
4752 #region Invocation of an array Field
4755 if ((bindingFlags & BindingFlags.GetField) != 0)
4761 idxCnt = argCnt - 1;
4766 // Verify that all of the index values are ints
4767 int[] idx = new int[idxCnt];
4768 for (int i=0;i<idxCnt;i++)
4772 idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
4774 catch (InvalidCastException)
4776 throw new ArgumentException(Environment.GetResourceString("Arg_IndexMustBeInt"));
4780 // Set or get the value...
4781 Array a = (Array) selFld.GetValue(target);
4783 // Set or get the value in the array
4784 if ((bindingFlags & BindingFlags.GetField) != 0)
4786 return a.GetValue(idx);
4790 a.SetValue(providedArgs[idxCnt],idx);
4799 #region Get the field value
4801 throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
4803 return selFld.GetValue(target);
4808 #region Set the field Value
4810 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
4812 selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
4820 if ((bindingFlags & BinderNonFieldGetSet) == 0)
4821 throw new MissingFieldException(FullName, name);
4825 #region Caching Logic
4827 bool useCache = false;
4829 // Note that when we add something to the cache, we are careful to ensure
4830 // that the actual providedArgs matches the parameters of the method. Otherwise,
4831 // some default argument processing has occurred. We don't want anyone
4832 // else with the same (insufficient) number of actual arguments to get a
4833 // cache hit because then they would bypass the default argument processing
4834 // and the invocation would fail.
4835 if (bDefaultBinder && namedParams == null && argCnt < 6)
4840 MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
4842 if (invokeMethod != null)
4843 return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
4848 #region Property PreConditions
4849 // @Legacy - This is RTM behavior
4850 bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
4851 bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
4853 if (isGetProperty || isSetProperty)
4855 #region Preconditions
4858 Contract.Assert(!IsSetField);
4861 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4865 Contract.Assert(isSetProperty);
4867 Contract.Assert(!IsGetField);
4869 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4870 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4876 MethodInfo[] finalists = null;
4877 MethodInfo finalist = null;
4879 #region BindingFlags.InvokeMethod
4880 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4882 #region Lookup Methods
4883 MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
4884 List<MethodInfo> results = null;
4886 for(int i = 0; i < semiFinalists.Length; i ++)
4888 MethodInfo semiFinalist = semiFinalists[i];
4889 Contract.Assert(semiFinalist != null);
4891 if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4894 if (finalist == null)
4896 finalist = semiFinalist;
4900 if (results == null)
4902 results = new List<MethodInfo>(semiFinalists.Length);
4903 results.Add(finalist);
4906 results.Add(semiFinalist);
4910 if (results != null)
4912 Contract.Assert(results.Count > 1);
4913 finalists = new MethodInfo[results.Count];
4914 results.CopyTo(finalists);
4920 Contract.Assert(finalists == null || finalist != null);
4922 #region BindingFlags.GetProperty or BindingFlags.SetProperty
4923 if (finalist == null && isGetProperty || isSetProperty)
4925 #region Lookup Property
4926 PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
4927 List<MethodInfo> results = null;
4929 for(int i = 0; i < semiFinalists.Length; i ++)
4931 MethodInfo semiFinalist = null;
4935 semiFinalist = semiFinalists[i].GetSetMethod(true);
4939 semiFinalist = semiFinalists[i].GetGetMethod(true);
4942 if (semiFinalist == null)
4945 if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4948 if (finalist == null)
4950 finalist = semiFinalist;
4954 if (results == null)
4956 results = new List<MethodInfo>(semiFinalists.Length);
4957 results.Add(finalist);
4960 results.Add(semiFinalist);
4964 if (results != null)
4966 Contract.Assert(results.Count > 1);
4967 finalists = new MethodInfo[results.Count];
4968 results.CopyTo(finalists);
4974 if (finalist != null)
4977 if (finalists == null &&
4979 finalist.GetParametersNoCopy().Length == 0 &&
4980 (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
4982 //if (useCache && argCnt == props[0].GetParameters().Length)
4983 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
4985 return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
4988 if (finalists == null)
4989 finalists = new MethodInfo[] { finalist };
4991 if (providedArgs == null)
4992 providedArgs = EmptyArray<Object>.Value;
4994 Object state = null;
4997 MethodBase invokeMethod = null;
4999 try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
5000 catch(MissingMethodException) { }
5002 if (invokeMethod == null)
5003 throw new MissingMethodException(FullName, name);
5005 //if (useCache && argCnt == invokeMethod.GetParameters().Length)
5006 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
5008 Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
5011 binder.ReorderArgumentArray(ref providedArgs, state);
5017 throw new MissingMethodException(FullName, name);
5023 #region Object Overrides
5025 public override bool Equals(object obj)
5027 // ComObjects are identified by the instance of the Type object and not the TypeHandle.
5028 return obj == (object)this;
5032 public override int GetHashCode()
5034 return RuntimeHelpers.GetHashCode(this);
5038 #if !FEATURE_CORECLR
5039 public static bool operator ==(RuntimeType left, RuntimeType right)
5041 return object.ReferenceEquals(left, right);
5044 public static bool operator !=(RuntimeType left, RuntimeType right)
5046 return !object.ReferenceEquals(left, right);
5048 #endif // !FEATURE_CORECLR
5050 public override String ToString()
5052 return GetCachedName(TypeNameKind.ToString);
5058 public Object Clone()
5064 #region ISerializable
5065 [System.Security.SecurityCritical] // auto-generated
5066 public void GetObjectData(SerializationInfo info, StreamingContext context)
5069 throw new ArgumentNullException("info");
5070 Contract.EndContractBlock();
5072 UnitySerializationHolder.GetUnitySerializationInfo(info, this);
5076 #region ICustomAttributeProvider
5077 [System.Security.SecuritySafeCritical] // auto-generated
5078 public override Object[] GetCustomAttributes(bool inherit)
5080 return CustomAttribute.GetCustomAttributes(this, RuntimeType.ObjectType, inherit);
5083 [System.Security.SecuritySafeCritical] // auto-generated
5084 public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
5086 if ((object)attributeType == null)
5087 throw new ArgumentNullException("attributeType");
5088 Contract.EndContractBlock();
5090 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5092 if (attributeRuntimeType == null)
5093 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5095 return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
5098 [System.Security.SecuritySafeCritical] // auto-generated
5099 public override bool IsDefined(Type attributeType, bool inherit)
5101 if ((object)attributeType == null)
5102 throw new ArgumentNullException("attributeType");
5103 Contract.EndContractBlock();
5105 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5107 if (attributeRuntimeType == null)
5108 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5110 return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
5113 public override IList<CustomAttributeData> GetCustomAttributesData()
5115 return CustomAttributeData.GetCustomAttributesInternal(this);
5119 #region MemberInfo Overrides
5121 public override String Name
5125 return GetCachedName(TypeNameKind.Name);
5130 // This is used by the ToString() overrides of all reflection types. The legacy behavior has the following problems:
5131 // 1. Use only Name for nested types, which can be confused with global types and generic parameters of the same name.
5132 // 2. Use only Name for generic parameters, which can be confused with nested types and global types of the same name.
5133 // 3. Remove the namespace ("System") for all primitive types, which is not language neutral.
5134 // 4. MethodBase.ToString() use "ByRef" for byref parameters which is different than Type.ToString().
5135 // 5. ConstructorInfo.ToString() outputs "Void" as the return type. Why Void?
5136 // Since it could be a breaking changes to fix these legacy behaviors, we only use the better and more unambiguous format
5137 // in serialization (MemberInfoSerializationHolder).
5138 internal override string FormatTypeName(bool serialization)
5142 return GetCachedName(TypeNameKind.SerializationName);
5146 Type elementType = GetRootElementType();
5148 // Legacy: this doesn't make sense, why use only Name for nested types but otherwise
5149 // ToString() which contains namespace.
5150 if (elementType.IsNested)
5153 string typeName = ToString();
5155 // Legacy: why removing "System"? Is it just because C# has keywords for these types?
5156 // If so why don't we change it to lower case to match the C# keyword casing?
5157 if (elementType.IsPrimitive ||
5158 elementType == typeof(void) ||
5159 elementType == typeof(TypedReference))
5161 typeName = typeName.Substring(@"System.".Length);
5169 private string GetCachedName(TypeNameKind kind)
5171 return Cache.GetName(kind);
5174 public override MemberTypes MemberType
5178 if (this.IsPublic || this.IsNotPublic)
5179 return MemberTypes.TypeInfo;
5181 return MemberTypes.NestedType;
5185 public override Type DeclaringType
5189 return Cache.GetEnclosingType();
5193 public override Type ReflectedType
5197 return DeclaringType;
5201 public override int MetadataToken
5203 [System.Security.SecuritySafeCritical] // auto-generated
5206 return RuntimeTypeHandle.GetToken(this);
5211 #region Legacy Internal
5212 private void CreateInstanceCheckThis()
5214 if (this is ReflectionOnlyType)
5215 throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
5217 if (ContainsGenericParameters)
5218 throw new ArgumentException(
5219 Environment.GetResourceString("Acc_CreateGenericEx", this));
5220 Contract.EndContractBlock();
5222 Type elementType = this.GetRootElementType();
5224 if (Object.ReferenceEquals(elementType, typeof(ArgIterator)))
5225 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateArgIterator"));
5227 if (Object.ReferenceEquals(elementType, typeof(void)))
5228 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateVoid"));
5231 [System.Security.SecurityCritical] // auto-generated
5232 internal Object CreateInstanceImpl(
5233 BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
5235 CreateInstanceCheckThis();
5237 Object server = null;
5243 // Store the activation attributes in thread local storage.
5244 // These attributes are later picked up by specialized
5245 // activation services like remote activation services to
5246 // influence the activation.
5247 #if FEATURE_REMOTING
5248 if(null != activationAttributes)
5250 ActivationServices.PushActivationAttributes(this, activationAttributes);
5255 args = EmptyArray<Object>.Value;
5257 int argCnt = args.Length;
5259 // Without a binder we need to do use the default binder...
5261 binder = DefaultBinder;
5263 // deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
5264 // so a call to GetMemberCons would fail
5265 if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
5266 && (IsGenericCOMObjectImpl() || IsValueType))
5268 server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0 , false, true, ref stackMark);
5272 ConstructorInfo[] candidates = GetConstructors(bindingAttr);
5273 List<MethodBase> matches = new List<MethodBase>(candidates.Length);
5275 // We cannot use Type.GetTypeArray here because some of the args might be null
5276 Type[] argsType = new Type[argCnt];
5277 for (int i = 0; i < argCnt; i++)
5279 if (args[i] != null)
5281 argsType[i] = args[i].GetType();
5285 for(int i = 0; i < candidates.Length; i ++)
5287 if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
5288 matches.Add(candidates[i]);
5291 MethodBase[] cons = new MethodBase[matches.Count];
5292 matches.CopyTo(cons);
5293 if (cons != null && cons.Length == 0)
5298 // Null out activation attributes before throwing exception
5299 #if FEATURE_REMOTING
5300 if(null != activationAttributes)
5302 ActivationServices.PopActivationAttributes(this);
5303 activationAttributes = null;
5306 throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5309 MethodBase invokeMethod;
5310 Object state = null;
5314 invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
5316 catch (MissingMethodException) { invokeMethod = null; }
5318 if (invokeMethod == null)
5320 #if FEATURE_REMOTING
5321 // Null out activation attributes before throwing exception
5322 if(null != activationAttributes)
5324 ActivationServices.PopActivationAttributes(this);
5325 activationAttributes = null;
5328 throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5331 #if FEATURE_MONO_CAS
5332 // If we're creating a delegate, we're about to call a
5333 // constructor taking an integer to represent a target
5334 // method. Since this is very difficult (and expensive)
5335 // to verify, we're just going to demand UnmanagedCode
5336 // permission before allowing this. Partially trusted
5337 // clients can instead use Delegate.CreateDelegate,
5338 // which allows specification of the target method via
5339 // name or MethodInfo.
5341 if (RuntimeType.DelegateType.IsAssignableFrom(invokeMethod.DeclaringType))
5344 // In CoreCLR, CAS is not exposed externally. So what we really are looking
5345 // for is to see if the external caller of this API is transparent or not.
5346 // We get that information from the fact that a Demand will succeed only if
5347 // the external caller is not transparent.
5350 #pragma warning disable 618
5351 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5352 #pragma warning restore 618
5356 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_DelegateCreationFromPT")));
5358 #else // FEATURE_CORECLR
5359 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5360 #endif // FEATURE_CORECLR
5362 #endif // FEATURE_MONO_CAS
5363 if (invokeMethod.GetParametersNoCopy().Length == 0)
5365 if (args.Length != 0)
5368 Contract.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
5369 CallingConventions.VarArgs);
5370 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
5371 Environment.GetResourceString("NotSupported_CallToVarArg")));
5374 #if MONO && FEATURE_REMOTING
5375 if (activationAttributes != null && activationAttributes.Length != 0) {
5376 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5380 server = Activator.CreateInstance(this, true);
5382 #if MONO && FEATURE_REMOTING
5388 #if MONO && FEATURE_REMOTING
5390 if (activationAttributes != null && activationAttributes.Length != 0) {
5391 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5394 server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
5395 #if MONO && FEATURE_REMOTING
5400 binder.ReorderArgumentArray(ref args, state);
5406 #if FEATURE_REMOTING
5407 // Reset the TLS to null
5408 if(null != activationAttributes)
5410 ActivationServices.PopActivationAttributes(this);
5411 activationAttributes = null;
5421 //Console.WriteLine(server);
5426 #if FEATURE_REMOTING
5428 // .NET seems to do this deep in method invocation which looks odd as it
5429 // needs extra push/pop as PushActivationAttributes/PopActivationAttributes.
5430 // We let them do nothing and have all logic here without complicated checks
5431 // inside fast path invoke.
5433 object ActivationCreateInstance (MethodBase invokeMethod, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
5435 var server = ActivationServices.CreateProxyFromAttributes (this, activationAttributes);
5437 invokeMethod.Invoke (server, bindingAttr, binder, args, culture);
5444 class ActivatorCacheEntry
5446 // the type to cache
5447 internal readonly RuntimeType m_type;
5448 // the delegate containing the call to the ctor, will be replaced by an IntPtr to feed a calli with
5449 internal volatile CtorDelegate m_ctor;
5450 internal readonly RuntimeMethodHandleInternal m_hCtorMethodHandle;
5451 internal readonly MethodAttributes m_ctorAttributes;
5452 // Is a security check needed before this constructor is invoked?
5453 internal readonly bool m_bNeedSecurityCheck;
5454 // Lazy initialization was performed
5455 internal volatile bool m_bFullyInitialized;
5457 [System.Security.SecurityCritical]
5458 internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh, bool bNeedSecurityCheck)
5461 m_bNeedSecurityCheck = bNeedSecurityCheck;
5462 m_hCtorMethodHandle = rmh;
5463 if (!m_hCtorMethodHandle.IsNullHandle())
5464 m_ctorAttributes = RuntimeMethodHandle.GetAttributes(m_hCtorMethodHandle);
5469 class ActivatorCache
5471 const int CACHE_SIZE = 16;
5472 volatile int hash_counter; //Counter for wrap around
5473 readonly ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE];
5475 volatile ConstructorInfo delegateCtorInfo;
5476 volatile PermissionSet delegateCreatePermissions;
5478 private void InitializeDelegateCreator() {
5479 // No synchronization needed here. In the worst case we create extra garbage
5480 PermissionSet ps = new PermissionSet(PermissionState.None);
5481 ps.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
5482 #pragma warning disable 618
5483 ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
5484 #pragma warning restore 618
5485 delegateCreatePermissions = ps;
5487 ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
5488 delegateCtorInfo = ctorInfo; // this assignment should be last
5491 [System.Security.SecuritySafeCritical] // auto-generated
5492 private void InitializeCacheEntry(ActivatorCacheEntry ace)
5494 if (!ace.m_type.IsValueType)
5496 Contract.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
5498 if (delegateCtorInfo == null)
5499 InitializeDelegateCreator();
5500 delegateCreatePermissions.Assert();
5502 // No synchronization needed here. In the worst case we create extra garbage
5503 CtorDelegate ctor = (CtorDelegate)delegateCtorInfo.Invoke(new Object[] { null, RuntimeMethodHandle.GetFunctionPointer(ace.m_hCtorMethodHandle) });
5506 ace.m_bFullyInitialized = true;
5509 internal ActivatorCacheEntry GetEntry(RuntimeType t)
5511 int index = hash_counter;
5512 for(int i = 0; i < CACHE_SIZE; i++)
5514 ActivatorCacheEntry ace = Volatile.Read(ref cache[index]);
5515 if (ace != null && ace.m_type == t) //check for type match..
5517 if (!ace.m_bFullyInitialized)
5518 InitializeCacheEntry(ace);
5521 index = (index+1)&(ActivatorCache.CACHE_SIZE-1);
5526 internal void SetEntry(ActivatorCacheEntry ace)
5528 // fill the the array backwards to hit the most recently filled entries first in GetEntry
5529 int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1);
5530 hash_counter = index;
5531 Volatile.Write(ref cache[index], ace);
5535 private static volatile ActivatorCache s_ActivatorCache;
5537 // the slow path of CreateInstanceDefaultCtor
5538 [System.Security.SecuritySafeCritical] // auto-generated
5539 internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
5541 RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
5542 bool bNeedSecurityCheck = true;
5543 bool bCanBeCached = false;
5544 bool bSecurityCheckOff = false;
5547 CreateInstanceCheckThis();
5550 bSecurityCheckOff = true;
5553 INVOCATION_FLAGS invocationFlags = InvocationFlags;
5554 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
5556 RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
5557 if (caller != null && !caller.IsSafeForReflection())
5558 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", this.FullName));
5560 // Allow it because the caller is framework code, but don't cache the result
5561 // because we need to do the stack walk every time this type is instantiated.
5562 bSecurityCheckOff = false;
5563 bCanBeCached = false;
5567 Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck);
5569 if (bCanBeCached && fillCache)
5571 ActivatorCache activatorCache = s_ActivatorCache;
5572 if (activatorCache == null)
5574 // No synchronization needed here. In the worst case we create extra garbage
5575 activatorCache = new ActivatorCache();
5576 s_ActivatorCache = activatorCache;
5580 ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
5581 activatorCache.SetEntry(ace);
5587 // Helper to invoke the default (parameterless) ctor.
5588 // fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
5589 [System.Security.SecuritySafeCritical] // auto-generated
5590 [DebuggerStepThroughAttribute]
5591 [Diagnostics.DebuggerHidden]
5592 internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
5594 if (GetType() == typeof(ReflectionOnlyType))
5595 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5597 ActivatorCache activatorCache = s_ActivatorCache;
5598 if (activatorCache != null)
5600 ActivatorCacheEntry ace = activatorCache.GetEntry(this);
5605 if (ace.m_ctor != null &&
5606 (ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5608 throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
5612 // Allocate empty object
5613 Object instance = RuntimeTypeHandle.Allocate(this);
5615 // if m_ctor is null, this type doesn't have a default ctor
5616 Contract.Assert(ace.m_ctor != null || this.IsValueType);
5618 if (ace.m_ctor != null)
5620 // Perform security checks if needed
5621 if (ace.m_bNeedSecurityCheck)
5622 RuntimeMethodHandle.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, this, (uint)INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
5624 // Call ctor (value types wont have any)
5627 ace.m_ctor(instance);
5631 throw new TargetInvocationException(e);
5638 return CreateInstanceSlow(publicOnly, skipCheckThis, fillCache, ref stackMark);
5641 internal void InvalidateCachedNestedType()
5643 Cache.InvalidateCachedNestedType();
5646 [System.Security.SecuritySafeCritical] // auto-generated
5647 internal bool IsGenericCOMObjectImpl()
5649 return RuntimeTypeHandle.IsComObject(this, true);
5654 #region Legacy Static Internal
5655 [System.Security.SecurityCritical]
5656 [ResourceExposure(ResourceScope.None)]
5657 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5658 private static extern Object _CreateEnum(RuntimeType enumType, long value);
5659 [System.Security.SecuritySafeCritical] // auto-generated
5660 internal static Object CreateEnum(RuntimeType enumType, long value)
5662 return _CreateEnum(enumType, value);
5665 #if FEATURE_COMINTEROP
5666 [System.Security.SecurityCritical] // auto-generated
5667 [ResourceExposure(ResourceScope.None)]
5668 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5669 private extern Object InvokeDispMethod(
5670 String name, BindingFlags invokeAttr, Object target, Object[] args,
5671 bool[] byrefModifiers, int culture, String[] namedParameters);
5673 #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5674 [System.Security.SecurityCritical] // auto-generated
5675 [ResourceExposure(ResourceScope.None)]
5676 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5677 internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
5679 [System.Security.SecurityCritical] // auto-generated
5680 [ResourceExposure(ResourceScope.None)]
5681 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5682 internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError);
5683 #else // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5684 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
5686 throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5689 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
5691 throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5693 #endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5699 #if FEATURE_COMINTEROP && FEATURE_REMOTING && !MONO
5700 [System.Security.SecuritySafeCritical] // auto-generated
5701 private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
5703 ParameterModifier[] aParamMod = null;
5706 // Allocate a new message
5707 Message reqMsg = new Message();
5708 reqMsg.InitFields(msgData);
5710 // Retrieve the required information from the message object.
5711 MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase();
5712 Object[] aArgs = reqMsg.Args;
5713 int cArgs = aArgs.Length;
5715 // Retrieve information from the method we are invoking on.
5716 ParameterInfo[] aParams = meth.GetParametersNoCopy();
5718 // If we have arguments, then set the byref flags to true for byref arguments.
5719 // We also wrap the arguments that require wrapping.
5722 ParameterModifier paramMod = new ParameterModifier(cArgs);
5723 for (int i = 0; i < cArgs; i++)
5725 if (aParams[i].ParameterType.IsByRef)
5729 aParamMod = new ParameterModifier[1];
5730 aParamMod[0] = paramMod;
5732 if (aWrapperTypes != null)
5733 WrapArgsForInvokeCall(aArgs, aWrapperTypes);
5736 // If the method has a void return type, then set the IgnoreReturn binding flag.
5737 if (Object.ReferenceEquals(meth.ReturnType, typeof(void)))
5738 flags |= BindingFlags.IgnoreReturn;
5742 // Invoke the method using InvokeMember().
5743 ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
5745 catch (TargetInvocationException e)
5747 // For target invocation exceptions, we need to unwrap the inner exception and
5749 throw e.InnerException;
5752 // Convert each byref argument that is not of the proper type to
5753 // the parameter type using the OleAutBinder.
5754 for (int i = 0; i < cArgs; i++)
5756 if (aParamMod[0][i] && aArgs[i] != null)
5758 // The parameter is byref.
5759 Type paramType = aParams[i].ParameterType.GetElementType();
5760 if (!Object.ReferenceEquals(paramType, aArgs[i].GetType()))
5761 aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
5765 // If the return type is not of the proper type, then convert it
5766 // to the proper type using the OleAutBinder.
5769 Type retType = meth.ReturnType;
5770 if (!Object.ReferenceEquals(retType, ret.GetType()))
5771 ret = ForwardCallBinder.ChangeType(ret, retType, null);
5774 // Propagate the out parameters
5775 RealProxy.PropagateOutParameters(reqMsg, aArgs, ret);
5777 // Return the value returned by the InvokeMember call.
5781 [SecuritySafeCritical]
5782 private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes)
5784 int cArgs = aArgs.Length;
5785 for (int i = 0; i < cArgs; i++)
5787 if (aWrapperTypes[i] == 0)
5790 if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
5792 Type wrapperType = null;
5793 bool isString = false;
5795 // Determine the type of wrapper to use.
5796 switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray)
5798 case DispatchWrapperType.Unknown:
5799 wrapperType = typeof(UnknownWrapper);
5801 case DispatchWrapperType.Dispatch:
5802 wrapperType = typeof(DispatchWrapper);
5804 case DispatchWrapperType.Error:
5805 wrapperType = typeof(ErrorWrapper);
5807 case DispatchWrapperType.Currency:
5808 wrapperType = typeof(CurrencyWrapper);
5810 case DispatchWrapperType.BStr:
5811 wrapperType = typeof(BStrWrapper);
5815 Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
5819 // Allocate the new array of wrappers.
5820 Array oldArray = (Array)aArgs[i];
5821 int numElems = oldArray.Length;
5822 Object[] newArray = (Object[])Array.UnsafeCreateInstance(wrapperType, numElems);
5824 // Retrieve the ConstructorInfo for the wrapper type.
5825 ConstructorInfo wrapperCons;
5828 wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
5832 wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)});
5835 // Wrap each of the elements of the array.
5836 for (int currElem = 0; currElem < numElems; currElem++)
5840 newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
5844 newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
5848 // Update the argument.
5849 aArgs[i] = newArray;
5853 // Determine the wrapper to use and then wrap the argument.
5854 switch ((DispatchWrapperType)aWrapperTypes[i])
5856 case DispatchWrapperType.Unknown:
5857 aArgs[i] = new UnknownWrapper(aArgs[i]);
5859 case DispatchWrapperType.Dispatch:
5860 aArgs[i] = new DispatchWrapper(aArgs[i]);
5862 case DispatchWrapperType.Error:
5863 aArgs[i] = new ErrorWrapper(aArgs[i]);
5865 case DispatchWrapperType.Currency:
5866 aArgs[i] = new CurrencyWrapper(aArgs[i]);
5868 case DispatchWrapperType.BStr:
5869 aArgs[i] = new BStrWrapper((String)aArgs[i]);
5872 Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified.");
5879 private OleAutBinder ForwardCallBinder
5883 // Synchronization is not required.
5884 if (s_ForwardCallBinder == null)
5885 s_ForwardCallBinder = new OleAutBinder();
5887 return s_ForwardCallBinder;
5892 private enum DispatchWrapperType : int
5894 // This enum must stay in [....] with the DispatchWrapperType enum defined in MLInfo.h
5895 Unknown = 0x00000001,
5896 Dispatch = 0x00000002,
5897 Record = 0x00000004,
5899 Currency = 0x00000010,
5901 SafeArray = 0x00010000
5904 private static volatile OleAutBinder s_ForwardCallBinder;
5905 #endif // FEATURE_COMINTEROP && FEATURE_REMOTING
5909 // this is the introspection only type. This type overrides all the functions with runtime semantics
5910 // and throws an exception.
5911 // The idea behind this type is that it relieves RuntimeType from doing honerous checks about ReflectionOnly
5913 // This type should not derive from RuntimeType but it's doing so for convinience.
5914 // That should not present a security threat though it is risky as a direct call to one of the base method
5915 // method (RuntimeType) and an instance of this type will work around the reason to have this type in the
5916 // first place. However given RuntimeType is not public all its methods are protected and require full trust
5919 internal class ReflectionOnlyType : RuntimeType {
5921 private ReflectionOnlyType() {}
5924 public override RuntimeTypeHandle TypeHandle
5928 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5935 internal unsafe struct Utf8String
5937 [System.Security.SecurityCritical] // auto-generated
5938 [ResourceExposure(ResourceScope.None)]
5939 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5940 private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz);
5942 [System.Security.SecurityCritical] // auto-generated
5943 [ResourceExposure(ResourceScope.None)]
5944 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
5945 [SuppressUnmanagedCodeSecurity]
5946 private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);
5948 [System.Security.SecurityCritical] // auto-generated
5949 [ResourceExposure(ResourceScope.None)]
5950 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
5951 [SuppressUnmanagedCodeSecurity]
5952 private static extern unsafe uint HashCaseInsensitive(void* sz, int cSz);
5954 [System.Security.SecurityCritical] // auto-generated
5955 private static int GetUtf8StringByteLength(void* pUtf8String)
5961 byte* pItr = (byte*)pUtf8String;
5974 private void* m_pStringHeap; // This is the raw UTF8 string.
5975 private int m_StringHeapByteLength;
5977 [System.Security.SecurityCritical] // auto-generated
5978 internal Utf8String(void* pStringHeap)
5980 m_pStringHeap = pStringHeap;
5981 if (pStringHeap != null)
5983 m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap);
5987 m_StringHeapByteLength = 0;
5991 [System.Security.SecurityCritical] // auto-generated
5992 internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
5994 m_pStringHeap = pUtf8String;
5995 m_StringHeapByteLength = cUtf8String;
5998 [System.Security.SecuritySafeCritical] // auto-generated
5999 internal unsafe bool Equals(Utf8String s)
6001 if (m_pStringHeap == null)
6003 return s.m_StringHeapByteLength == 0;
6005 if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6007 return Utf8String.EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6012 [System.Security.SecuritySafeCritical] // auto-generated
6013 internal unsafe bool EqualsCaseInsensitive(Utf8String s)
6015 if (m_pStringHeap == null)
6017 return s.m_StringHeapByteLength == 0;
6019 if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6021 return Utf8String.EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6026 [System.Security.SecuritySafeCritical] // auto-generated
6027 internal unsafe uint HashCaseInsensitive()
6029 return Utf8String.HashCaseInsensitive(m_pStringHeap, m_StringHeapByteLength);
6032 [System.Security.SecuritySafeCritical] // auto-generated
6033 public override string ToString()
6037 byte* buf = stackalloc byte[m_StringHeapByteLength];
6038 byte* pItr = (byte*)m_pStringHeap;
6040 for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++)
6042 buf[currentPos] = *pItr;
6046 if (m_StringHeapByteLength == 0)
6049 int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength);
6050 char* result = stackalloc char[cResult];
6051 Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult);
6052 return new string(result, 0, cResult);
6060 namespace System.Reflection
6062 // Reliable hashtable thread safe for multiple readers and single writer. Note that the reliability goes together with thread
6063 // safety. Thread safety for multiple readers requires atomic update of the state that also makes makes the table
6064 // reliable in the presence of asynchronous exceptions.
6065 internal struct CerHashtable<K, V> where K : class
6069 // Note that m_keys and m_values arrays are immutable to allow lock-free reads. A new instance
6070 // of CerHashtable has to be allocated to grow the size of the hashtable.
6071 internal K[] m_keys;
6072 internal V[] m_values;
6073 internal int m_count;
6075 internal Table(int size)
6077 size = HashHelpers.GetPrime(size);
6078 m_keys = new K[size];
6079 m_values = new V[size];
6082 internal void Insert(K key, V value)
6085 int hashcode = GetHashCodeHelper(key);
6087 hashcode = ~hashcode;
6090 int index = hashcode % keys.Length;
6094 K hit = keys[index];
6099 m_values[index] = value;
6101 // This volatile write has to be last. It is going to publish the result atomically.
6103 // Note that incrementing the count or setting the value does not do any harm without setting the key. The inconsistency will be ignored
6104 // and it will go away completely during next rehash.
6105 Volatile.Write(ref keys[index], key);
6111 Contract.Assert(!hit.Equals(key), "Key was already in CerHashtable! Potential ---- (or bug) in the Reflection cache?");
6114 if (index >= keys.Length)
6115 index -= keys.Length;
6121 private Table m_Table;
6123 private const int MinSize = 7;
6125 private static int GetHashCodeHelper(K key)
6127 string sKey = key as string;
6129 // For strings we don't want the key to differ across domains as CerHashtable might be shared.
6132 return key.GetHashCode();
6137 return sKey.GetLegacyNonRandomizedHashCode();
6141 private void Rehash(int newSize)
6143 Table newTable = new Table(newSize);
6145 Table oldTable = m_Table;
6146 if (oldTable != null)
6148 K[] keys = oldTable.m_keys;
6149 V[] values = oldTable.m_values;
6151 for (int i = 0; i < keys.Length; i++)
6157 newTable.Insert(key, values[i]);
6162 // Publish the new table atomically
6163 Volatile.Write(ref m_Table, newTable);
6166 internal V this[K key]
6170 Table table = m_Table;
6174 int requiredSize = 2 * (table.m_count + 1);
6175 if (requiredSize >= table.m_keys.Length)
6176 Rehash(requiredSize);
6183 m_Table.Insert(key, value);
6187 Table table = Volatile.Read(ref m_Table);
6191 int hashcode = GetHashCodeHelper(key);
6193 hashcode = ~hashcode;
6195 K[] keys = table.m_keys;
6196 int index = hashcode % keys.Length;
6200 // This volatile read has to be first. It is reading the atomically published result.
6201 K hit = Volatile.Read(ref keys[index]);
6205 if (hit.Equals(key))
6206 return table.m_values[index];
6209 if (index >= keys.Length)
6210 index -= keys.Length;