[System.Private.CoreLib] Remove unused members and further cleanups
[mono-project.git] / mcs / class / referencesource / mscorlib / system / rttype.cs
blobc5d4a4a7e9ecc6f4e11fc57cb3b614c54c301f2e
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 //
7 // File: RtType.cs
8 //
9 // <OWNER>Microsoft</OWNER>
11 // Implements System.RuntimeType
13 // ======================================================================================
16 using System;
17 using System.Reflection;
18 using System.Runtime.ConstrainedExecution;
19 using System.Globalization;
20 using System.Threading;
21 using System.Diagnostics;
22 #if !NETCORE
23 using System.Security.Permissions;
24 #endif
25 using System.Collections;
26 using System.Collections.Generic;
27 using System.Runtime;
28 using System.Runtime.Serialization;
29 using System.Runtime.CompilerServices;
30 using System.Security;
31 using System.Text;
32 using System.Runtime.Remoting;
33 #if FEATURE_REMOTING
34 using System.Runtime.Remoting.Proxies;
35 using System.Runtime.Remoting.Messaging;
36 using System.Runtime.Remoting.Activation;
37 using System.Runtime.Remoting.Metadata;
38 #endif
39 #if !MONO
40 using MdSigCallingConvention = System.Signature.MdSigCallingConvention;
41 using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
42 #endif
43 using System.Runtime.InteropServices;
44 using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
45 #if !MONO
46 using MdToken = System.Reflection.MetadataToken;
47 #endif
48 using System.Runtime.Versioning;
49 using System.Diagnostics.Contracts;
51 #if MONO || NETCORE
52 using CustomAttribute=System.MonoCustomAttrs;
53 #endif
55 namespace System
57 // this is a work around to get the concept of a calli. It's not as fast but it would be interesting to
58 // see how it compares to the current implementation.
59 // This delegate will disappear at some point in favor of calli
61 internal delegate void CtorDelegate(Object instance);
63 // Keep this in sync with FormatFlags defined in typestring.h
64 internal enum TypeNameFormatFlags
66 FormatBasic = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
67 FormatNamespace = 0x00000001, // Include namespace and/or enclosing class names in type names
68 FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
69 FormatAssembly = 0x00000004, // Include assembly display name in type names
70 FormatSignature = 0x00000008, // Include signature in method names
71 FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names
72 #if _DEBUG
73 FormatDebug = 0x00000020, // For debug printing of types only
74 #endif
75 FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
76 FormatStubInfo = 0x00000080, // Include stub info like {unbox-stub}
77 FormatGenericParam = 0x00000100, // Use !name and !!name for generic type and method parameters
79 // If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
80 // we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
81 // and including the assembly name will normally increase the size of the serialized data and also decrease the performance.
82 FormatSerialization = FormatNamespace |
83 FormatGenericParam |
84 FormatFullInst
87 internal enum TypeNameKind
89 Name,
90 ToString,
91 SerializationName,
92 FullName,
95 [Serializable]
96 internal partial class RuntimeType :
97 System.Reflection.TypeInfo, ISerializable, ICloneable
99 #region Definitions
101 internal enum MemberListType
103 All,
104 CaseSensitive,
105 CaseInsensitive,
106 HandleToInfo
109 // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
110 private struct ListBuilder<T> where T : class
112 T[] _items;
113 T _item;
114 int _count;
115 int _capacity;
117 public ListBuilder(int capacity)
119 _items = null;
120 _item = null;
121 _count = 0;
122 _capacity = capacity;
125 public T this[int index]
129 Contract.Requires(index < Count);
130 return (_items != null) ? _items[index] : _item;
132 #if FEATURE_LEGACYNETCF
133 // added for Dev11 466969 quirk
136 Contract.Requires(index < Count);
137 if (_items != null)
138 _items[index] = value;
139 else
140 _item = value;
142 #endif
145 public T[] ToArray()
147 if (_count == 0)
148 return Array.Empty<T> ();
149 if (_count == 1)
150 return new T[1] { _item };
152 Array.Resize(ref _items, _count);
153 _capacity = _count;
154 return _items;
157 public void CopyTo(Object[] array, int index)
159 if (_count == 0)
160 return;
162 if (_count == 1)
164 array[index] = _item;
165 return;
168 Array.Copy(_items, 0, array, index, _count);
171 public int Count
175 return _count;
179 public void Add(T item)
181 if (_count == 0)
183 _item = item;
185 else
187 if (_count == 1)
189 if (_capacity < 2)
190 _capacity = 4;
191 _items = new T[_capacity];
192 _items[0] = _item;
194 else
195 if (_capacity == _count)
197 int newCapacity = 2 * _capacity;
198 Array.Resize(ref _items, newCapacity);
199 _capacity = newCapacity;
202 _items[_count] = item;
204 _count++;
207 #if !MONO
208 internal class RuntimeTypeCache
210 private const int MAXNAMELEN = 1024;
212 #region Definitions
213 internal enum CacheType
215 Method,
216 Constructor,
217 Field,
218 Property,
219 Event,
220 Interface,
221 NestedType
224 private struct Filter
226 private Utf8String m_name;
227 private MemberListType m_listType;
228 private uint m_nameHash;
230 [System.Security.SecurityCritical] // auto-generated
231 public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
233 this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
234 this.m_listType = listType;
235 this.m_nameHash = 0;
237 if (RequiresStringComparison())
239 m_nameHash = m_name.HashCaseInsensitive();
243 public bool Match(Utf8String name)
245 bool retVal = true;
247 if (m_listType == MemberListType.CaseSensitive)
248 retVal = m_name.Equals(name);
249 else if (m_listType == MemberListType.CaseInsensitive)
250 retVal = m_name.EqualsCaseInsensitive(name);
252 // Currently the callers of UsesStringComparison assume that if it returns false
253 // then the match always succeeds and can be skipped. Assert that this is maintained.
254 Contract.Assert(retVal || RequiresStringComparison());
256 return retVal;
259 // Does the current match type require a string comparison?
260 // If not, we know Match will always return true and the call can be skipped
261 // If so, we know we can have a valid hash to check against from GetHashToMatch
262 public bool RequiresStringComparison()
264 return (m_listType == MemberListType.CaseSensitive) ||
265 (m_listType == MemberListType.CaseInsensitive);
268 public bool CaseSensitive()
270 return (m_listType == MemberListType.CaseSensitive);
273 public uint GetHashToMatch()
275 Contract.Assert(RequiresStringComparison());
277 return m_nameHash;
281 private class MemberInfoCache<T> where T : MemberInfo
283 #region Private Data Members
285 // MemberInfo caches
286 private CerHashtable<string, T[]> m_csMemberInfos;
287 private CerHashtable<string, T[]> m_cisMemberInfos;
288 // List of MemberInfos given out. When m_cacheComplete is false, it may have null entries at the end to avoid
289 // reallocating the list every time a new entry is added.
290 private T[] m_allMembers;
291 private bool m_cacheComplete;
292 #if FEATURE_LEGACYNETCF
293 // Dev11 466969 quirk
294 private List<RuntimePropertyInfo> m_ambiguousProperties;
295 #endif
297 // This is the strong reference back to the cache
298 private RuntimeTypeCache m_runtimeTypeCache;
299 #endregion
301 #region Constructor
302 #if MDA_SUPPORTED
303 [System.Security.SecuritySafeCritical] // auto-generated
304 #endif
305 internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
307 #if MDA_SUPPORTED
308 Mda.MemberInfoCacheCreation();
309 #endif
310 m_runtimeTypeCache = runtimeTypeCache;
313 #if FEATURE_LEGACYNETCF
314 // Dev11 466969 quirk
315 internal IReadOnlyList<RuntimePropertyInfo> AmbiguousProperties { get { return m_ambiguousProperties; } }
317 private void InitializeAndUpdateAmbiguousPropertiesList(RuntimePropertyInfo parent, RuntimePropertyInfo child)
319 Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
321 if (m_ambiguousProperties == null)
323 List<RuntimePropertyInfo> newList = new List<RuntimePropertyInfo>();
324 Interlocked.CompareExchange(ref m_ambiguousProperties, newList, null);
327 lock (m_ambiguousProperties)
329 // record the parent type in case it needs to be pruned later.
330 Contract.Assert(child.DeclaringType.IsSubclassOf(parent.DeclaringType));
331 m_ambiguousProperties.Add(parent);
334 #endif
336 [System.Security.SecuritySafeCritical] // auto-generated
337 internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
339 T[] list = null;
340 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method);
341 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
342 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
343 bool isInherited = declaringType != ReflectedType;
344 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
345 switch (cacheType)
347 case CacheType.Method:
348 list = (T[])(object)new RuntimeMethodInfo[1] {
349 new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null)
351 break;
352 case CacheType.Constructor:
353 list = (T[])(object)new RuntimeConstructorInfo[1] {
354 new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)
356 break;
359 Insert(ref list, null, MemberListType.HandleToInfo);
361 return (MethodBase)(object)list[0];
364 [System.Security.SecuritySafeCritical] // auto-generated
365 internal FieldInfo AddField(RuntimeFieldHandleInternal field)
367 // create the runtime field info
368 FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field);
369 bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
370 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
371 RuntimeType approxDeclaringType = RuntimeFieldHandle.GetApproxDeclaringType(field);
372 bool isInherited = RuntimeFieldHandle.AcquiresContextFromThis(field) ?
373 !RuntimeTypeHandle.CompareCanonicalHandles(approxDeclaringType, ReflectedType) :
374 approxDeclaringType != ReflectedType;
376 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
378 T[] list = (T[])(object)new RuntimeFieldInfo[1] {
379 new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags)
382 Insert(ref list, null, MemberListType.HandleToInfo);
384 return (FieldInfo)(object)list[0];
387 [System.Security.SecuritySafeCritical] // auto-generated
388 private unsafe T[] Populate(string name, MemberListType listType, CacheType cacheType)
390 T[] list = null;
392 if (name == null || name.Length == 0 ||
393 (cacheType == CacheType.Constructor && name.FirstChar != '.' && name.FirstChar != '*'))
395 list = GetListByName(null, 0, null, 0, listType, cacheType);
397 else
399 int cNameLen = name.Length;
400 fixed (char* pName = name)
402 int cUtf8Name = Encoding.UTF8.GetByteCount(pName, cNameLen);
403 // allocating on the stack is faster than allocating on the GC heap
404 // but we surely don't want to cause a stack overflow
405 // no one should be looking for a member whose name is longer than 1024
406 if (cUtf8Name > MAXNAMELEN)
408 fixed (byte* pUtf8Name = new byte[cUtf8Name])
410 list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
413 else
415 byte* pUtf8Name = stackalloc byte[cUtf8Name];
416 list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
421 Insert(ref list, name, listType);
423 return list;
426 [System.Security.SecurityCritical] // auto-generated
427 private unsafe T[] GetListByName(char* pName, int cNameLen, byte* pUtf8Name, int cUtf8Name, MemberListType listType, CacheType cacheType)
429 if (cNameLen != 0)
430 Encoding.UTF8.GetBytes(pName, cNameLen, pUtf8Name, cUtf8Name);
432 Filter filter = new Filter(pUtf8Name, cUtf8Name, listType);
433 Object list = null;
435 switch (cacheType)
437 case CacheType.Method:
438 list = PopulateMethods(filter);
439 break;
440 case CacheType.Field:
441 list = PopulateFields(filter);
442 break;
443 case CacheType.Constructor:
444 list = PopulateConstructors(filter);
445 break;
446 case CacheType.Property:
447 list = PopulateProperties(filter);
448 break;
449 case CacheType.Event:
450 list = PopulateEvents(filter);
451 break;
452 case CacheType.NestedType:
453 list = PopulateNestedClasses(filter);
454 break;
455 case CacheType.Interface:
456 list = PopulateInterfaces(filter);
457 break;
458 default:
459 BCLDebug.Assert(true, "Invalid CacheType");
460 break;
463 return (T[])list;
466 // May replace the list with a new one if certain cache
467 // lookups succeed. Also, may modify the contents of the list
468 // after merging these new data structures with cached ones.
469 [System.Security.SecuritySafeCritical] // auto-generated
470 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
471 internal void Insert(ref T[] list, string name, MemberListType listType)
473 bool lockTaken = false;
475 RuntimeHelpers.PrepareConstrainedRegions();
476 try
478 Monitor.Enter(this, ref lockTaken);
480 switch (listType)
482 case MemberListType.CaseSensitive:
484 // Ensure we always return a list that has
485 // been merged with the global list.
486 T[] cachedList = m_csMemberInfos[name];
487 if (cachedList == null)
489 MergeWithGlobalList(list);
490 m_csMemberInfos[name] = list;
492 else
493 list = cachedList;
495 break;
497 case MemberListType.CaseInsensitive:
499 // Ensure we always return a list that has
500 // been merged with the global list.
501 T[] cachedList = m_cisMemberInfos[name];
502 if (cachedList == null)
504 MergeWithGlobalList(list);
505 m_cisMemberInfos[name] = list;
507 else
508 list = cachedList;
510 break;
512 case MemberListType.All:
513 if (!m_cacheComplete)
515 MergeWithGlobalList(list);
517 // Trim null entries at the end of m_allMembers array
518 int memberCount = m_allMembers.Length;
519 while (memberCount > 0)
521 if (m_allMembers[memberCount-1] != null)
522 break;
523 memberCount--;
525 Array.Resize(ref m_allMembers, memberCount);
527 Volatile.Write(ref m_cacheComplete, true);
529 // We want the behavior where the results are returned in the same order on the phone
530 #if !FEATURE_LEGACYNETCF
531 else
532 #endif
533 list = m_allMembers;
534 break;
536 default:
537 MergeWithGlobalList(list);
538 break;
541 finally
543 if (lockTaken)
545 Monitor.Exit(this);
550 // Modifies the existing list.
551 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
552 private void MergeWithGlobalList(T[] list)
554 T[] cachedMembers = m_allMembers;
556 if (cachedMembers == null)
558 m_allMembers = list;
559 return;
562 int cachedCount = cachedMembers.Length;
563 int freeSlotIndex = 0;
565 for (int i = 0; i < list.Length; i++)
567 T newMemberInfo = list[i];
568 bool foundInCache = false;
570 int cachedIndex;
571 for (cachedIndex = 0; cachedIndex < cachedCount; cachedIndex++)
573 T cachedMemberInfo = cachedMembers[cachedIndex];
574 if (cachedMemberInfo == null)
575 break;
577 if (newMemberInfo.CacheEquals(cachedMemberInfo))
579 list[i] = cachedMemberInfo;
580 foundInCache = true;
581 break;
585 if (!foundInCache)
587 if (freeSlotIndex == 0)
588 freeSlotIndex = cachedIndex;
590 if (freeSlotIndex >= cachedMembers.Length)
592 int newSize;
593 if (m_cacheComplete)
596 // In theory, we should never add more elements to the cache when it is complete.
598 // Unfortunately, we shipped with bugs that cause changes of the complete cache (DevDiv #339308).
599 // Grow the list by exactly one element in this case to avoid null entries at the end.
602 // DevDiv #339308 is fixed, but we are keeping this code here for Dev11 in case there are other instances of this bug.
603 // Remove for Dev12.
605 Contract.Assert(false);
607 newSize = cachedMembers.Length + 1;
609 else
611 newSize = Math.Max(Math.Max(4, 2 * cachedMembers.Length), list.Length);
614 // Use different variable for ref argument to Array.Resize to allow enregistration of cachedMembers by the JIT
615 T[] cachedMembers2 = cachedMembers;
616 Array.Resize(ref cachedMembers2, newSize);
617 cachedMembers = cachedMembers2;
620 Contract.Assert(cachedMembers[freeSlotIndex] == null);
621 cachedMembers[freeSlotIndex] = newMemberInfo;
622 freeSlotIndex++;
626 m_allMembers = cachedMembers;
628 #endregion
630 #region Population Logic
632 [System.Security.SecuritySafeCritical] // auto-generated
633 private unsafe RuntimeMethodInfo[] PopulateMethods(Filter filter)
635 ListBuilder<RuntimeMethodInfo> list = new ListBuilder<RuntimeMethodInfo>();
637 RuntimeType declaringType = ReflectedType;
638 Contract.Assert(declaringType != null);
640 if (RuntimeTypeHandle.IsInterface(declaringType))
642 #region IsInterface
644 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
646 if (filter.RequiresStringComparison())
648 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
650 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
651 continue;
654 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
655 continue;
658 #region Loop through all methods on the interface
659 Contract.Assert(!methodHandle.IsNullHandle());
660 // Except for .ctor, .cctor, IL_STUB*, and static methods, all interface methods should be abstract, virtual, and non-RTSpecialName.
661 // Note that this assumption will become invalid when we add support for non-abstract or static methods on interfaces.
662 Contract.Assert(
663 (RuntimeMethodHandle.GetAttributes(methodHandle) & (MethodAttributes.RTSpecialName | MethodAttributes.Abstract | MethodAttributes.Virtual)) == (MethodAttributes.Abstract | MethodAttributes.Virtual) ||
664 (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.Static) == MethodAttributes.Static ||
665 RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
666 RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor") ||
667 RuntimeMethodHandle.GetName(methodHandle).StartsWith("IL_STUB", StringComparison.Ordinal));
669 #region Calculate Binding Flags
670 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
671 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
672 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
673 bool isInherited = false;
674 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
675 #endregion
677 if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
678 continue;
680 // get the unboxing stub or instantiating stub if needed
681 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
683 RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
684 instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
686 list.Add(runtimeMethodInfo);
687 #endregion
689 #endregion
691 else
693 #region IsClass or GenericParameter
694 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
695 declaringType = declaringType.GetBaseType();
697 bool* overrides = stackalloc bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
698 bool isValueType = declaringType.IsValueType;
702 int vtableSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
704 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
706 if (filter.RequiresStringComparison())
708 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
710 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
711 continue;
714 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
715 continue;
718 #region Loop through all methods on the current type
719 Contract.Assert(!methodHandle.IsNullHandle());
721 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
722 MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;
724 #region Continue if this is a constructor
725 Contract.Assert(
726 (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.RTSpecialName) == 0 ||
727 RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
728 RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor"));
730 if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
731 continue;
732 #endregion
734 #region Continue if this is a private declared on a base type
735 bool isVirtual = false;
736 int methodSlot = 0;
737 if ((methodAttributes & MethodAttributes.Virtual) != 0)
739 // only virtual if actually in the vtableslot range, but GetSlot will
740 // assert if an EnC method, which can't be virtual, so narrow down first
741 // before calling GetSlot
742 methodSlot = RuntimeMethodHandle.GetSlot(methodHandle);
743 isVirtual = (methodSlot < vtableSlots);
746 bool isInherited = declaringType != ReflectedType;
748 // NetCF actually includes private methods from parent classes in Reflection results
749 // We will mimic that in Mango Compat mode.
750 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
752 bool isPrivate = methodAccess == MethodAttributes.Private;
753 if (isInherited && isPrivate && !isVirtual)
754 continue;
756 #endregion
758 #region Continue if this is a virtual and is already overridden
759 if (isVirtual)
761 Contract.Assert(
762 (methodAttributes & MethodAttributes.Abstract) != 0 ||
763 (methodAttributes & MethodAttributes.Virtual) != 0 ||
764 RuntimeMethodHandle.GetDeclaringType(methodHandle) != declaringType);
766 if (overrides[methodSlot] == true)
767 continue;
769 overrides[methodSlot] = true;
771 else if (isValueType)
773 if ((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) != 0)
774 continue;
776 else
778 Contract.Assert((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0);
780 #endregion
782 #region Calculate Binding Flags
783 bool isPublic = methodAccess == MethodAttributes.Public;
784 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
785 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
786 #endregion
788 // get the unboxing stub or instantiating stub if needed
789 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
791 RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
792 instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
794 list.Add(runtimeMethodInfo);
795 #endregion
798 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
799 } while (declaringType != null);
800 #endregion
803 return list.ToArray();
806 [System.Security.SecuritySafeCritical] // auto-generated
807 private RuntimeConstructorInfo[] PopulateConstructors(Filter filter)
809 if (ReflectedType.IsGenericParameter)
811 return EmptyArray<RuntimeConstructorInfo>.Value;
814 ListBuilder<RuntimeConstructorInfo> list = new ListBuilder<RuntimeConstructorInfo>();
816 RuntimeType declaringType= ReflectedType;
818 foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
820 if (filter.RequiresStringComparison())
822 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
824 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
825 continue;
828 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
829 continue;
832 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
834 Contract.Assert(!methodHandle.IsNullHandle());
836 if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
837 continue;
839 // Constructors should not be virtual or abstract
840 Contract.Assert(
841 (methodAttributes & MethodAttributes.Abstract) == 0 &&
842 (methodAttributes & MethodAttributes.Virtual) == 0);
844 #region Calculate Binding Flags
845 bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
846 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
847 bool isInherited = false;
848 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
849 #endregion
851 // get the unboxing stub or instantiating stub if needed
852 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
854 RuntimeConstructorInfo runtimeConstructorInfo =
855 new RuntimeConstructorInfo(instantiatedHandle, ReflectedType, m_runtimeTypeCache, methodAttributes, bindingFlags);
857 list.Add(runtimeConstructorInfo);
860 return list.ToArray();
863 [System.Security.SecuritySafeCritical] // auto-generated
864 private unsafe RuntimeFieldInfo[] PopulateFields(Filter filter)
866 ListBuilder<RuntimeFieldInfo> list = new ListBuilder<RuntimeFieldInfo>();
868 RuntimeType declaringType = ReflectedType;
870 #region Populate all static, instance and literal fields
871 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
872 declaringType = declaringType.GetBaseType();
874 while(declaringType != null)
876 PopulateRtFields(filter, declaringType, ref list);
878 PopulateLiteralFields(filter, declaringType, ref list);
880 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
882 #endregion
884 #region Populate Literal Fields on Interfaces
885 if (ReflectedType.IsGenericParameter)
887 Type[] interfaces = ReflectedType.BaseType.GetInterfaces();
889 for (int i = 0; i < interfaces.Length; i++)
891 // Populate literal fields defined on any of the interfaces implemented by the declaring type
892 PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
893 PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
896 else
898 Type[] interfaces = RuntimeTypeHandle.GetInterfaces(ReflectedType);
900 if (interfaces != null)
902 for (int i = 0; i < interfaces.Length; i++)
904 // Populate literal fields defined on any of the interfaces implemented by the declaring type
905 PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
906 PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
910 #endregion
912 return list.ToArray();
915 [System.Security.SecuritySafeCritical] // auto-generated
916 private unsafe void PopulateRtFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
918 IntPtr* pResult = stackalloc IntPtr[64];
919 int count = 64;
921 if (!RuntimeTypeHandle.GetFields(declaringType, pResult, &count))
923 fixed(IntPtr* pBigResult = new IntPtr[count])
925 RuntimeTypeHandle.GetFields(declaringType, pBigResult, &count);
926 PopulateRtFields(filter, pBigResult, count, declaringType, ref list);
929 else if (count > 0)
931 PopulateRtFields(filter, pResult, count, declaringType, ref list);
935 [System.Security.SecurityCritical] // auto-generated
936 private unsafe void PopulateRtFields(Filter filter,
937 IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
939 Contract.Requires(declaringType != null);
940 Contract.Requires(ReflectedType != null);
942 bool needsStaticFieldForGeneric = RuntimeTypeHandle.HasInstantiation(declaringType) && !RuntimeTypeHandle.ContainsGenericVariables(declaringType);
943 bool isInherited = declaringType != ReflectedType;
945 for(int i = 0; i < count; i ++)
947 RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(ppFieldHandles[i]);
949 if (filter.RequiresStringComparison())
951 if (!RuntimeFieldHandle.MatchesNameHash(runtimeFieldHandle, filter.GetHashToMatch()))
953 Contract.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
954 continue;
957 if (!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)))
958 continue;
961 Contract.Assert(!runtimeFieldHandle.IsNullHandle());
963 FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(runtimeFieldHandle);
964 FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
966 if (isInherited)
968 if (fieldAccess == FieldAttributes.Private)
969 continue;
972 #region Calculate Binding Flags
973 bool isPublic = fieldAccess == FieldAttributes.Public;
974 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
975 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
976 #endregion
978 // correct the FieldDesc if needed
979 if (needsStaticFieldForGeneric && isStatic)
980 runtimeFieldHandle = RuntimeFieldHandle.GetStaticFieldForGenericType(runtimeFieldHandle, declaringType);
982 RuntimeFieldInfo runtimeFieldInfo =
983 new RtFieldInfo(runtimeFieldHandle, declaringType, m_runtimeTypeCache, bindingFlags);
985 list.Add(runtimeFieldInfo);
989 [System.Security.SecuritySafeCritical] // auto-generated
990 private unsafe void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
992 Contract.Requires(declaringType != null);
993 Contract.Requires(ReflectedType != null);
995 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
997 // Our policy is that TypeDescs do not have metadata tokens
998 if (MdToken.IsNullToken(tkDeclaringType))
999 return;
1001 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1003 MetadataEnumResult tkFields;
1004 scope.EnumFields(tkDeclaringType, out tkFields);
1006 for (int i = 0; i < tkFields.Length; i++)
1008 int tkField = tkFields[i];
1009 Contract.Assert(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
1010 Contract.Assert(!MdToken.IsNullToken(tkField));
1012 FieldAttributes fieldAttributes;
1013 scope.GetFieldDefProps(tkField, out fieldAttributes);
1015 FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
1017 if ((fieldAttributes & FieldAttributes.Literal) != 0)
1019 bool isInherited = declaringType != ReflectedType;
1020 if (isInherited)
1022 bool isPrivate = fieldAccess == FieldAttributes.Private;
1023 if (isPrivate)
1024 continue;
1027 if (filter.RequiresStringComparison())
1029 Utf8String name;
1030 name = scope.GetName(tkField);
1032 if (!filter.Match(name))
1033 continue;
1036 #region Calculate Binding Flags
1037 bool isPublic = fieldAccess == FieldAttributes.Public;
1038 bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
1039 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
1040 #endregion
1042 RuntimeFieldInfo runtimeFieldInfo =
1043 new MdFieldInfo(tkField, fieldAttributes, declaringType.GetTypeHandleInternal(), m_runtimeTypeCache, bindingFlags);
1045 list.Add(runtimeFieldInfo);
1050 private static void AddElementTypes(Type template, IList<Type> types)
1052 if (!template.HasElementType)
1053 return;
1055 AddElementTypes(template.GetElementType(), types);
1057 for (int i = 0; i < types.Count; i ++)
1059 if (template.IsArray)
1061 if (template.IsSzArray)
1062 types[i] = types[i].MakeArrayType();
1063 else
1064 types[i] = types[i].MakeArrayType(template.GetArrayRank());
1066 else if (template.IsPointer)
1068 types[i] = types[i].MakePointerType();
1073 private void AddSpecialInterface(ref ListBuilder<RuntimeType> list, Filter filter, RuntimeType iList, bool addSubInterface)
1075 if (iList.IsAssignableFrom(ReflectedType))
1077 if (filter.Match(RuntimeTypeHandle.GetUtf8Name(iList)))
1078 list.Add(iList);
1080 if (addSubInterface)
1082 Type[] iFaces = iList.GetInterfaces();
1083 for (int j = 0; j < iFaces.Length; j++)
1085 RuntimeType iFace = (RuntimeType)iFaces[j];
1086 if (iFace.IsGenericType && filter.Match(RuntimeTypeHandle.GetUtf8Name(iFace)))
1087 list.Add(iFace);
1094 [System.Security.SecuritySafeCritical] // auto-generated
1095 private RuntimeType[] PopulateInterfaces(Filter filter)
1097 ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1099 RuntimeType declaringType = ReflectedType;
1101 if (!RuntimeTypeHandle.IsGenericVariable(declaringType))
1103 Type[] ifaces = RuntimeTypeHandle.GetInterfaces(declaringType);
1105 if (ifaces != null)
1107 for (int i = 0; i < ifaces.Length; i++)
1109 RuntimeType interfaceType = (RuntimeType)ifaces[i];
1111 if (filter.RequiresStringComparison())
1113 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
1114 continue;
1117 Contract.Assert(interfaceType.IsInterface);
1118 list.Add(interfaceType);
1122 if (ReflectedType.IsSzArray)
1124 RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType();
1126 if (!arrayType.IsPointer)
1128 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IList<>).MakeGenericType(arrayType), true);
1130 // To avoid adding a duplicate IEnumerable<T>, we don't add the sub interfaces of IReadOnlyList.
1131 // Instead, we add IReadOnlyCollection<T> separately.
1132 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyList<>).MakeGenericType(arrayType), false);
1133 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyCollection<>).MakeGenericType(arrayType), false);
1137 else
1139 List<RuntimeType> al = new List<RuntimeType>();
1141 // Get all constraints
1142 Type[] constraints = declaringType.GetGenericParameterConstraints();
1144 // Populate transitive closure of all interfaces in constraint set
1145 for (int i = 0; i < constraints.Length; i++)
1147 RuntimeType constraint = (RuntimeType)constraints[i];
1148 if (constraint.IsInterface)
1149 al.Add(constraint);
1151 Type[] temp = constraint.GetInterfaces();
1152 for (int j = 0; j < temp.Length; j++)
1153 al.Add(temp[j] as RuntimeType);
1156 // Remove duplicates
1157 Dictionary<RuntimeType, RuntimeType> ht = new Dictionary<RuntimeType, RuntimeType>();
1158 for (int i = 0; i < al.Count; i++)
1160 RuntimeType constraint = al[i];
1161 if (!ht.ContainsKey(constraint))
1162 ht[constraint] = constraint;
1165 RuntimeType[] interfaces = new RuntimeType[ht.Values.Count];
1166 ht.Values.CopyTo(interfaces, 0);
1168 // Populate link-list
1169 for (int i = 0; i < interfaces.Length; i++)
1171 if (filter.RequiresStringComparison())
1173 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaces[i])))
1174 continue;
1177 list.Add(interfaces[i]);
1181 return list.ToArray();
1184 [System.Security.SecuritySafeCritical] // auto-generated
1185 private unsafe RuntimeType[] PopulateNestedClasses(Filter filter)
1187 RuntimeType declaringType = ReflectedType;
1189 while (RuntimeTypeHandle.IsGenericVariable(declaringType))
1191 declaringType = declaringType.GetBaseType();
1194 int tkEnclosingType = RuntimeTypeHandle.GetToken(declaringType);
1196 // For example, TypeDescs do not have metadata tokens
1197 if (MdToken.IsNullToken(tkEnclosingType))
1198 return EmptyArray<RuntimeType>.Value;
1200 ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1202 RuntimeModule moduleHandle = RuntimeTypeHandle.GetModule(declaringType);
1203 MetadataImport scope = ModuleHandle.GetMetadataImport(moduleHandle);
1205 MetadataEnumResult tkNestedClasses;
1206 scope.EnumNestedTypes(tkEnclosingType, out tkNestedClasses);
1208 for (int i = 0; i < tkNestedClasses.Length; i++)
1210 RuntimeType nestedType = null;
1214 nestedType = ModuleHandle.ResolveTypeHandleInternal(moduleHandle, tkNestedClasses[i], null, null);
1216 catch(System.TypeLoadException)
1218 // In a reflection emit scenario, we may have a token for a class which
1219 // has not been baked and hence cannot be loaded.
1220 continue;
1223 if (filter.RequiresStringComparison())
1225 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(nestedType)))
1226 continue;
1229 list.Add(nestedType);
1232 return list.ToArray();
1235 [System.Security.SecuritySafeCritical] // auto-generated
1236 private unsafe RuntimeEventInfo[] PopulateEvents(Filter filter)
1238 Contract.Requires(ReflectedType != null);
1240 // Do not create the dictionary if we are filtering the properties by name already
1241 Dictionary<String, RuntimeEventInfo> csEventInfos = filter.CaseSensitive() ? null :
1242 new Dictionary<String, RuntimeEventInfo>();
1244 RuntimeType declaringType = ReflectedType;
1245 ListBuilder<RuntimeEventInfo> list = new ListBuilder<RuntimeEventInfo>();
1247 if (!RuntimeTypeHandle.IsInterface(declaringType))
1249 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1250 declaringType = declaringType.GetBaseType();
1252 // Populate associates off of the class hierarchy
1253 while(declaringType != null)
1255 PopulateEvents(filter, declaringType, csEventInfos, ref list);
1256 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1259 else
1261 // Populate associates for this interface
1262 PopulateEvents(filter, declaringType, csEventInfos, ref list);
1265 return list.ToArray();
1268 [System.Security.SecuritySafeCritical] // auto-generated
1269 private unsafe void PopulateEvents(
1270 Filter filter, RuntimeType declaringType, Dictionary<String, RuntimeEventInfo> csEventInfos, ref ListBuilder<RuntimeEventInfo> list)
1272 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1274 // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1275 if (MdToken.IsNullToken(tkDeclaringType))
1276 return;
1278 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1280 MetadataEnumResult tkEvents;
1281 scope.EnumEvents(tkDeclaringType, out tkEvents);
1283 for (int i = 0; i < tkEvents.Length; i++)
1285 int tkEvent = tkEvents[i];
1286 bool isPrivate;
1288 Contract.Assert(!MdToken.IsNullToken(tkEvent));
1289 Contract.Assert(MdToken.IsTokenOfType(tkEvent, MetadataTokenType.Event));
1291 if (filter.RequiresStringComparison())
1293 Utf8String name;
1294 name = scope.GetName(tkEvent);
1296 if (!filter.Match(name))
1297 continue;
1300 RuntimeEventInfo eventInfo = new RuntimeEventInfo(
1301 tkEvent, declaringType, m_runtimeTypeCache, out isPrivate);
1303 #region Remove Inherited Privates
1304 if (declaringType != m_runtimeTypeCache.GetRuntimeType() && isPrivate)
1305 continue;
1306 #endregion
1308 #region Remove Duplicates
1309 if (csEventInfos != null)
1311 string name = eventInfo.Name;
1313 if (csEventInfos.GetValueOrDefault(name) != null)
1314 continue;
1316 csEventInfos[name] = eventInfo;
1318 else
1320 if (list.Count > 0)
1321 break;
1323 #endregion
1325 list.Add(eventInfo);
1329 [System.Security.SecuritySafeCritical] // auto-generated
1330 private unsafe RuntimePropertyInfo[] PopulateProperties(Filter filter)
1332 Contract.Requires(ReflectedType != null);
1334 // m_csMemberInfos can be null at this point. It will be initialized when Insert
1335 // is called in Populate after this returns.
1337 RuntimeType declaringType = ReflectedType;
1338 Contract.Assert(declaringType != null);
1340 ListBuilder<RuntimePropertyInfo> list = new ListBuilder<RuntimePropertyInfo>();
1342 if (!RuntimeTypeHandle.IsInterface(declaringType))
1344 while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1345 declaringType = declaringType.GetBaseType();
1347 // Do not create the dictionary if we are filtering the properties by name already
1348 Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos = filter.CaseSensitive() ? null :
1349 new Dictionary<String, List<RuntimePropertyInfo>>();
1351 // All elements automatically initialized to false.
1352 bool[] usedSlots = new bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
1354 // Populate associates off of the class hierarchy
1357 PopulateProperties(filter, declaringType, csPropertyInfos, usedSlots, ref list);
1358 declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1359 } while (declaringType != null);
1361 else
1363 // Populate associates for this interface
1364 PopulateProperties(filter, declaringType, null, null, ref list);
1367 return list.ToArray();
1370 [System.Security.SecuritySafeCritical] // auto-generated
1371 private unsafe void PopulateProperties(
1372 Filter filter,
1373 RuntimeType declaringType,
1374 Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos,
1375 bool[] usedSlots,
1376 ref ListBuilder<RuntimePropertyInfo> list)
1378 int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1380 // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1381 if (MdToken.IsNullToken(tkDeclaringType))
1382 return;
1384 MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1386 MetadataEnumResult tkProperties;
1387 scope.EnumProperties(tkDeclaringType, out tkProperties);
1389 RuntimeModule declaringModuleHandle = RuntimeTypeHandle.GetModule(declaringType);
1391 int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType);
1393 Contract.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) ||
1394 (!declaringType.IsInterface && usedSlots != null && usedSlots.Length >= numVirtuals));
1396 for (int i = 0; i < tkProperties.Length; i++)
1398 int tkProperty = tkProperties[i];
1399 bool isPrivate;
1401 Contract.Assert(!MdToken.IsNullToken(tkProperty));
1402 Contract.Assert(MdToken.IsTokenOfType(tkProperty, MetadataTokenType.Property));
1404 if (filter.RequiresStringComparison())
1406 if (!ModuleHandle.ContainsPropertyMatchingHash(declaringModuleHandle, tkProperty, filter.GetHashToMatch()))
1408 Contract.Assert(!filter.Match(declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty)));
1409 continue;
1412 Utf8String name;
1413 name = declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty);
1415 if (!filter.Match(name))
1416 continue;
1419 RuntimePropertyInfo propertyInfo =
1420 new RuntimePropertyInfo(
1421 tkProperty, declaringType, m_runtimeTypeCache, out isPrivate);
1423 // If this is a class, not an interface
1424 if (usedSlots != null)
1426 #region Remove Privates
1427 if (declaringType != ReflectedType && isPrivate)
1428 continue;
1429 #endregion
1431 #region Duplicate check based on vtable slots
1433 // The inheritance of properties are defined by the inheritance of their
1434 // getters and setters.
1435 // A property on a base type is "overriden" by a property on a sub type
1436 // if the getter/setter of the latter occupies the same vtable slot as
1437 // the getter/setter of the former.
1439 MethodInfo associateMethod = propertyInfo.GetGetMethod();
1440 if (associateMethod == null)
1442 // We only need to examine the setter if a getter doesn't exist.
1443 // It is not logical for the getter to be virtual but not the setter.
1444 associateMethod = propertyInfo.GetSetMethod();
1447 if (associateMethod != null)
1449 int slot = RuntimeMethodHandle.GetSlot((RuntimeMethodInfo)associateMethod);
1451 if (slot < numVirtuals)
1453 Contract.Assert(associateMethod.IsVirtual);
1454 if (usedSlots[slot] == true)
1455 continue;
1456 else
1457 usedSlots[slot] = true;
1460 #endregion
1462 #region Duplicate check based on name and signature
1464 // For backward compatibility, even if the vtable slots don't match, we will still treat
1465 // a property as duplicate if the names and signatures match.
1467 if (csPropertyInfos != null)
1469 string name = propertyInfo.Name;
1471 List<RuntimePropertyInfo> cache = csPropertyInfos.GetValueOrDefault(name);
1473 if (cache == null)
1475 cache = new List<RuntimePropertyInfo>(1);
1476 csPropertyInfos[name] = cache;
1479 for (int j = 0; j < cache.Count; j++)
1481 if (propertyInfo.EqualsSig(cache[j]))
1483 #if FEATURE_LEGACYNETCF
1484 // Dev11 466969 quirk
1485 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(cache[j]))
1487 InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, cache[j]);
1489 else
1490 #endif
1492 cache = null;
1493 break;
1498 if (cache == null)
1499 continue;
1501 cache.Add(propertyInfo);
1503 else
1505 bool duplicate = false;
1507 for (int j = 0; j < list.Count; j++)
1509 if (propertyInfo.EqualsSig(list[j]))
1511 #if FEATURE_LEGACYNETCF
1512 // Dev11 466969 quirk
1513 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(list[j]))
1515 InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, list[j]);
1517 else
1518 #endif
1520 duplicate = true;
1521 break;
1526 if (duplicate)
1527 continue;
1529 #endregion
1532 list.Add(propertyInfo);
1535 #endregion
1537 #region NonPrivate Members
1538 internal T[] GetMemberList(MemberListType listType, string name, CacheType cacheType)
1540 T[] list = null;
1542 switch(listType)
1544 case MemberListType.CaseSensitive:
1545 list = m_csMemberInfos[name];
1546 if (list != null)
1547 return list;
1549 return Populate(name, listType, cacheType);
1551 case MemberListType.CaseInsensitive:
1552 list = m_cisMemberInfos[name];
1553 if (list != null)
1554 return list;
1556 return Populate(name, listType, cacheType);
1558 default:
1559 Contract.Assert(listType == MemberListType.All);
1560 if (Volatile.Read(ref m_cacheComplete))
1561 return m_allMembers;
1563 return Populate(null, listType, cacheType);
1567 internal RuntimeType ReflectedType
1571 return m_runtimeTypeCache.GetRuntimeType();
1574 #endregion
1576 #endregion
1578 #region Private Data Members
1579 private RuntimeType m_runtimeType;
1580 private RuntimeType m_enclosingType;
1581 private TypeCode m_typeCode;
1582 private string m_name;
1583 private string m_fullname;
1584 private string m_toString;
1585 private string m_namespace;
1586 private string m_serializationname;
1587 private bool m_isGlobal;
1588 private bool m_bIsDomainInitialized;
1589 private MemberInfoCache<RuntimeMethodInfo> m_methodInfoCache;
1590 private MemberInfoCache<RuntimeConstructorInfo> m_constructorInfoCache;
1591 private MemberInfoCache<RuntimeFieldInfo> m_fieldInfoCache;
1592 private MemberInfoCache<RuntimeType> m_interfaceCache;
1593 private MemberInfoCache<RuntimeType> m_nestedClassesCache;
1594 private MemberInfoCache<RuntimePropertyInfo> m_propertyInfoCache;
1595 private MemberInfoCache<RuntimeEventInfo> m_eventInfoCache;
1596 private static CerHashtable<RuntimeMethodInfo, RuntimeMethodInfo> s_methodInstantiations;
1597 private static Object s_methodInstantiationsLock;
1598 #if !FEATURE_CORECLR
1599 private RuntimeConstructorInfo m_serializationCtor;
1600 #endif
1601 private string m_defaultMemberName;
1602 private Object m_genericCache; // Generic cache for rare scenario specific data. It is used to cache Enum names and values.
1603 #endregion
1605 #region Constructor
1606 internal RuntimeTypeCache(RuntimeType runtimeType)
1608 m_typeCode = TypeCode.Empty;
1609 m_runtimeType = runtimeType;
1610 m_isGlobal = RuntimeTypeHandle.GetModule(runtimeType).RuntimeType == runtimeType;
1612 #endregion
1614 #region Private Members
1615 private string ConstructName(ref string name, TypeNameFormatFlags formatFlags)
1617 if (name == null)
1619 name = new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags);
1621 return name;
1624 private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType)
1625 where T : MemberInfo
1627 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1628 return existingCache.GetMemberList(listType, name, cacheType);
1631 #if FEATURE_LEGACYNETCF
1632 // Dev11 466969 quirk
1633 private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
1634 where T : MemberInfo
1636 Contract.Assert(cacheType == CacheType.Property);
1638 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1639 T[] results = existingCache.GetMemberList(listType, name, cacheType);
1641 // must access property after GetMemberList() has been called
1642 ambiguousProperties = existingCache.AmbiguousProperties;
1644 // we should only have an ambiguous properties list in Mango-compat mode
1645 Contract.Assert(ambiguousProperties == null || CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
1646 return results;
1648 #endif
1650 private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T> m_cache)
1651 where T : MemberInfo
1653 MemberInfoCache<T> existingCache = m_cache;
1655 if (existingCache == null)
1657 MemberInfoCache<T> newCache = new MemberInfoCache<T>(this);
1658 existingCache = Interlocked.CompareExchange(ref m_cache, newCache, null);
1659 if (existingCache == null)
1660 existingCache = newCache;
1663 return existingCache;
1665 #endregion
1667 #region Internal Members
1669 internal Object GenericCache
1671 get { return m_genericCache; }
1672 set { m_genericCache = value; }
1675 internal bool DomainInitialized
1677 get { return m_bIsDomainInitialized; }
1678 set { m_bIsDomainInitialized = value; }
1681 internal string GetName(TypeNameKind kind)
1683 switch (kind)
1685 case TypeNameKind.Name:
1686 // No namespace, full instantiation, and assembly.
1687 return ConstructName(ref m_name, TypeNameFormatFlags.FormatBasic);
1689 case TypeNameKind.FullName:
1690 // We exclude the types that contain generic parameters because their names cannot be roundtripped.
1691 // We allow generic type definitions (and their refs, ptrs, and arrays) because their names can be roundtriped.
1692 // Theoretically generic types instantiated with generic type definitions can be roundtripped, e.g. List`1<Dictionary`2>.
1693 // But these kind of types are useless, rare, and hard to identity. We would need to recursively examine all the
1694 // generic arguments with the same criteria. We will exclude them unless we see a real user scenario.
1695 if (!m_runtimeType.GetRootElementType().IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters)
1696 return null;
1698 // No assembly.
1699 return ConstructName(ref m_fullname, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst);
1701 case TypeNameKind.ToString:
1702 // No full instantiation and assembly.
1703 return ConstructName(ref m_toString, TypeNameFormatFlags.FormatNamespace);
1705 case TypeNameKind.SerializationName:
1706 // Use FormatGenericParam in serialization. Otherwise we won't be able
1707 // to distinguish between a generic parameter and a normal type with the same name.
1708 // e.g. Foo<T>.Bar(T t), the parameter type T could be !1 or a real type named "T".
1709 // Excluding the version number in the assembly name for VTS.
1710 return ConstructName(ref m_serializationname, TypeNameFormatFlags.FormatSerialization);
1712 default:
1713 throw new InvalidOperationException();
1717 [System.Security.SecuritySafeCritical]
1718 internal unsafe string GetNameSpace()
1720 // @Optimization - Use ConstructName to populate m_namespace
1721 if (m_namespace == null)
1723 Type type = m_runtimeType;
1724 type = type.GetRootElementType();
1726 while (type.IsNested)
1727 type = type.DeclaringType;
1729 m_namespace = RuntimeTypeHandle.GetMetadataImport((RuntimeType)type).GetNamespace(type.MetadataToken).ToString();
1732 return m_namespace;
1735 internal TypeCode TypeCode
1737 get { return m_typeCode; }
1738 set { m_typeCode = value; }
1741 [System.Security.SecuritySafeCritical] // auto-generated
1742 internal unsafe RuntimeType GetEnclosingType()
1744 if (m_enclosingType == null)
1746 // Use void as a marker of null enclosing type
1747 RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
1748 Contract.Assert(enclosingType != typeof(void));
1749 m_enclosingType = enclosingType ?? (RuntimeType)typeof(void);
1752 return (m_enclosingType == typeof(void)) ? null : m_enclosingType;
1755 internal RuntimeType GetRuntimeType()
1757 return m_runtimeType;
1760 internal bool IsGlobal
1762 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1763 get { return m_isGlobal; }
1766 internal void InvalidateCachedNestedType()
1768 m_nestedClassesCache = null;
1771 #if !FEATURE_CORECLR
1772 internal RuntimeConstructorInfo GetSerializationCtor()
1774 if (m_serializationCtor == null)
1776 if (s_SICtorParamTypes == null)
1777 s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
1779 m_serializationCtor = m_runtimeType.GetConstructor(
1780 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
1781 null,
1782 CallingConventions.Any,
1783 s_SICtorParamTypes,
1784 null) as RuntimeConstructorInfo;
1787 return m_serializationCtor;
1789 #endif //!FEATURE_CORECLR
1791 internal string GetDefaultMemberName()
1793 if (m_defaultMemberName == null)
1795 CustomAttributeData attr = null;
1796 Type DefaultMemberAttrType = typeof(DefaultMemberAttribute);
1797 for (RuntimeType t = m_runtimeType; t != null; t = t.GetBaseType())
1799 IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes(t);
1800 for (int i = 0; i < attrs.Count; i++)
1802 if (Object.ReferenceEquals(attrs[i].Constructor.DeclaringType, DefaultMemberAttrType))
1804 attr = attrs[i];
1805 break;
1809 if (attr != null)
1811 m_defaultMemberName = attr.ConstructorArguments[0].Value as string;
1812 break;
1817 return m_defaultMemberName;
1819 #endregion
1821 #region Caches Accessors
1822 [System.Security.SecurityCritical] // auto-generated
1823 internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandleInternal genericMethod)
1825 LoaderAllocator la = RuntimeMethodHandle.GetLoaderAllocator(genericMethod);
1827 RuntimeMethodInfo rmi = new RuntimeMethodInfo(
1828 genericMethod, RuntimeMethodHandle.GetDeclaringType(genericMethod), this,
1829 RuntimeMethodHandle.GetAttributes(genericMethod), (BindingFlags)(-1), la);
1831 RuntimeMethodInfo crmi;
1832 if (la != null)
1834 crmi = la.m_methodInstantiations[rmi];
1836 else
1838 crmi = s_methodInstantiations[rmi];
1840 if (crmi != null)
1841 return crmi;
1843 if (s_methodInstantiationsLock == null)
1844 Interlocked.CompareExchange(ref s_methodInstantiationsLock, new Object(), null);
1846 bool lockTaken = false;
1847 RuntimeHelpers.PrepareConstrainedRegions();
1850 Monitor.Enter(s_methodInstantiationsLock, ref lockTaken);
1852 if (la != null)
1854 crmi = la.m_methodInstantiations[rmi];
1855 if (crmi != null)
1856 return crmi;
1857 la.m_methodInstantiations[rmi] = rmi;
1859 else
1861 crmi = s_methodInstantiations[rmi];
1862 if (crmi != null)
1863 return crmi;
1864 s_methodInstantiations[rmi] = rmi;
1867 finally
1869 if (lockTaken)
1871 Monitor.Exit(s_methodInstantiationsLock);
1875 return rmi;
1878 internal RuntimeMethodInfo[] GetMethodList(MemberListType listType, string name)
1880 return GetMemberList<RuntimeMethodInfo>(ref m_methodInfoCache, listType, name, CacheType.Method);
1883 internal RuntimeConstructorInfo[] GetConstructorList(MemberListType listType, string name)
1885 return GetMemberList<RuntimeConstructorInfo>(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
1888 internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name)
1890 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property);
1893 #if FEATURE_LEGACYNETCF
1894 // Dev11 466969 quirk
1895 internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
1897 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property, out ambiguousProperties);
1899 #endif
1901 internal RuntimeEventInfo[] GetEventList(MemberListType listType, string name)
1903 return GetMemberList<RuntimeEventInfo>(ref m_eventInfoCache, listType, name, CacheType.Event);
1906 internal RuntimeFieldInfo[] GetFieldList(MemberListType listType, string name)
1908 return GetMemberList<RuntimeFieldInfo>(ref m_fieldInfoCache, listType, name, CacheType.Field);
1911 internal RuntimeType[] GetInterfaceList(MemberListType listType, string name)
1913 return GetMemberList<RuntimeType>(ref m_interfaceCache, listType, name, CacheType.Interface);
1916 internal RuntimeType[] GetNestedTypeList(MemberListType listType, string name)
1918 return GetMemberList<RuntimeType>(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
1921 internal MethodBase GetMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method)
1923 GetMemberCache<RuntimeMethodInfo>(ref m_methodInfoCache);
1924 return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method);
1927 internal MethodBase GetConstructor(RuntimeType declaringType, RuntimeMethodHandleInternal constructor)
1929 GetMemberCache<RuntimeConstructorInfo>(ref m_constructorInfoCache);
1930 return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor);
1933 internal FieldInfo GetField(RuntimeFieldHandleInternal field)
1935 GetMemberCache<RuntimeFieldInfo>(ref m_fieldInfoCache);
1936 return m_fieldInfoCache.AddField(field);
1939 #endregion
1941 #endif
1942 #endregion
1944 #if FEATURE_REMOTING && !MONO
1945 #region Legacy Remoting Cache
1946 // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
1947 // This member is currently being used by Remoting for caching remoting data. If you
1948 // need to cache data here, talk to the Remoting team to work out a mechanism, so that
1949 // both caching systems can happily work together.
1950 private RemotingTypeCachedData m_cachedData;
1952 internal RemotingTypeCachedData RemotingCache
1956 // This grabs an internal copy of m_cachedData and uses
1957 // that instead of looking at m_cachedData directly because
1958 // the cache may get cleared asynchronously. This prevents
1959 // us from having to take a lock.
1960 RemotingTypeCachedData cache = m_cachedData;
1961 if (cache == null)
1963 cache = new RemotingTypeCachedData(this);
1964 RemotingTypeCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
1965 if (ret != null)
1966 cache = ret;
1968 return cache;
1971 #endregion
1972 #endif //FEATURE_REMOTING
1974 #region Static Members
1976 #region Internal
1978 internal static RuntimeType GetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly,
1979 ref StackCrawlMark stackMark)
1981 if (typeName == null)
1982 throw new ArgumentNullException("typeName");
1983 Contract.EndContractBlock();
1985 #if FEATURE_LEGACYNETCF
1986 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && typeName.Length == 0)
1987 throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
1988 #endif
1990 return RuntimeTypeHandle.GetTypeByName(
1991 typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
1994 #if !MONO
1995 internal static MethodBase GetMethodBase(RuntimeModule scope, int typeMetadataToken)
1997 return GetMethodBase(ModuleHandle.ResolveMethodHandleInternal(scope, typeMetadataToken));
2000 internal static MethodBase GetMethodBase(IRuntimeMethodInfo methodHandle)
2002 return GetMethodBase(null, methodHandle);
2005 [System.Security.SecuritySafeCritical]
2006 internal static MethodBase GetMethodBase(RuntimeType reflectedType, IRuntimeMethodInfo methodHandle)
2008 MethodBase retval = RuntimeType.GetMethodBase(reflectedType, methodHandle.Value);
2009 GC.KeepAlive(methodHandle);
2010 return retval;
2013 [System.Security.SecurityCritical] // auto-generated
2014 internal unsafe static MethodBase GetMethodBase(RuntimeType reflectedType, RuntimeMethodHandleInternal methodHandle)
2016 Contract.Assert(!methodHandle.IsNullHandle());
2018 if (RuntimeMethodHandle.IsDynamicMethod(methodHandle))
2020 Resolver resolver = RuntimeMethodHandle.GetResolver(methodHandle);
2022 if (resolver != null)
2023 return resolver.GetDynamicMethod();
2025 return null;
2028 // verify the type/method relationship
2029 RuntimeType declaredType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
2031 RuntimeType[] methodInstantiation = null;
2033 if (reflectedType == null)
2034 reflectedType = declaredType as RuntimeType;
2036 if (reflectedType != declaredType && !reflectedType.IsSubclassOf(declaredType))
2038 // object[] is assignable from string[].
2039 if (reflectedType.IsArray)
2043 // The whole purpose of this chunk of code is not only for error checking.
2044 // GetMember has a side effect of populating the member cache of reflectedType,
2045 // doing so will ensure we construct the correct MethodInfo/ConstructorInfo objects.
2046 // Without this the reflectedType.Cache.GetMethod call below may return a MethodInfo
2047 // object whose ReflectedType is string[] and DeclaringType is object[]. That would
2048 // be (arguabally) incorrect because string[] is not a subclass of object[].
2049 MethodBase[] methodBases = reflectedType.GetMember(
2050 RuntimeMethodHandle.GetName(methodHandle), MemberTypes.Constructor | MemberTypes.Method,
2051 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) as MethodBase[];
2053 bool loaderAssuredCompatible = false;
2054 for (int i = 0; i < methodBases.Length; i++)
2056 IRuntimeMethodInfo rmi = (IRuntimeMethodInfo)methodBases[i];
2057 if (rmi.Value.Value == methodHandle.Value)
2058 loaderAssuredCompatible = true;
2061 if (!loaderAssuredCompatible)
2062 throw new ArgumentException(String.Format(
2063 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2064 reflectedType.ToString(), declaredType.ToString()));
2066 // Action<in string> is assignable from, but not a subclass of Action<in object>.
2067 else if (declaredType.IsGenericType)
2069 // ignoring instantiation is the ReflectedType a subtype of the DeclaringType
2070 RuntimeType declaringDefinition = (RuntimeType)declaredType.GetGenericTypeDefinition();
2072 RuntimeType baseType = reflectedType;
2074 while (baseType != null)
2076 RuntimeType baseDefinition = baseType;
2078 if (baseDefinition.IsGenericType && !baseType.IsGenericTypeDefinition)
2079 baseDefinition = (RuntimeType)baseDefinition.GetGenericTypeDefinition();
2081 if (baseDefinition == declaringDefinition)
2082 break;
2084 baseType = baseType.GetBaseType();
2087 if (baseType == null)
2089 // ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
2090 throw new ArgumentException(String.Format(
2091 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2092 reflectedType.ToString(), declaredType.ToString()));
2095 // remap the method to same method on the subclass ReflectedType
2096 declaredType = baseType;
2098 // if the original methodHandle was the definition then we don't need to rebind generic method arguments
2099 // because all RuntimeMethodHandles retrieved off of the canonical method table are definitions. That's
2100 // why for everything else we need to rebind the generic method arguments.
2101 if (!RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2103 methodInstantiation = RuntimeMethodHandle.GetMethodInstantiationInternal(methodHandle);
2106 // lookup via v-table slot the RuntimeMethodHandle on the new declaring type
2107 methodHandle = RuntimeMethodHandle.GetMethodFromCanonical(methodHandle, declaredType);
2109 else if (!declaredType.IsAssignableFrom(reflectedType))
2111 // declaredType is not Array, not generic, and not assignable from reflectedType
2112 throw new ArgumentException(String.Format(
2113 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2114 reflectedType.ToString(), declaredType.ToString()));
2118 // If methodInstantiation is not null, GetStubIfNeeded will rebind the generic method arguments
2119 // if declaredType is an instantiated generic type and methodHandle is not generic, get the instantiated MethodDesc (if needed)
2120 // if declaredType is a value type, get the unboxing stub (if needed)
2122 // this is so that our behavior here is consistent with that of Type.GetMethod
2123 // See MemberInfoCache<RuntimeConstructorInfo>.PopulateMethods and MemberInfoCache<RuntimeMethodInfoInfo>.PopulateConstructors
2125 methodHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaredType, methodInstantiation);
2126 MethodBase retval;
2128 if (RuntimeMethodHandle.IsConstructor(methodHandle))
2130 // Constructor case: constructors cannot be generic
2131 retval = reflectedType.Cache.GetConstructor(declaredType, methodHandle);
2133 else
2135 // Method case
2136 if (RuntimeMethodHandle.HasMethodInstantiation(methodHandle) && !RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2137 retval = reflectedType.Cache.GetGenericMethodInfo(methodHandle);
2138 else
2139 retval = reflectedType.Cache.GetMethod(declaredType, methodHandle);
2142 GC.KeepAlive(methodInstantiation);
2143 return retval;
2146 internal Object GenericCache
2148 get { return Cache.GenericCache; }
2149 set { Cache.GenericCache = value; }
2152 internal bool DomainInitialized
2154 get { return Cache.DomainInitialized; }
2155 set { Cache.DomainInitialized = value; }
2158 [System.Security.SecuritySafeCritical] // auto-generated
2159 internal unsafe static FieldInfo GetFieldInfo(IRuntimeFieldInfo fieldHandle)
2161 return GetFieldInfo(RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle), fieldHandle);
2164 [System.Security.SecuritySafeCritical] // auto-generated
2165 internal unsafe static FieldInfo GetFieldInfo(RuntimeType reflectedType, IRuntimeFieldInfo field)
2167 RuntimeFieldHandleInternal fieldHandle = field.Value;
2169 // verify the type/method relationship
2170 if (reflectedType == null)
2172 reflectedType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2174 else
2176 RuntimeType declaredType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2177 if (reflectedType != declaredType)
2179 if (!RuntimeFieldHandle.AcquiresContextFromThis(fieldHandle) ||
2180 !RuntimeTypeHandle.CompareCanonicalHandles(declaredType, reflectedType))
2182 throw new ArgumentException(String.Format(
2183 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
2184 reflectedType.ToString(),
2185 declaredType.ToString()));
2190 FieldInfo retVal = reflectedType.Cache.GetField(fieldHandle);
2191 GC.KeepAlive(field);
2192 return retVal;
2195 // Called internally
2196 private unsafe static PropertyInfo GetPropertyInfo(RuntimeType reflectedType, int tkProperty)
2198 RuntimePropertyInfo property = null;
2199 RuntimePropertyInfo[] candidates =
2200 reflectedType.Cache.GetPropertyList(MemberListType.All, null);
2202 for (int i = 0; i < candidates.Length; i++)
2204 property = candidates[i];
2205 if (property.MetadataToken == tkProperty)
2206 return property;
2209 Contract.Assume(false, "Unreachable code");
2210 throw new SystemException();
2212 #endif
2213 private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
2215 if (type.IsPointer || type.IsByRef || type == typeof(void))
2216 throw new ArgumentException(
2217 Environment.GetResourceString("Argument_NeverValidGenericArgument", type.ToString()));
2221 internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
2223 if (genericArguments == null)
2224 throw new ArgumentNullException();
2225 Contract.EndContractBlock();
2227 for(int i = 0; i < genericArguments.Length; i++)
2229 if (genericArguments[i] == null)
2230 throw new ArgumentNullException();
2232 ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
2235 if (genericArguments.Length != genericParamters.Length)
2236 throw new ArgumentException(
2237 Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
2239 #if !MONO
2240 [System.Security.SecuritySafeCritical] // auto-generated
2241 internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
2243 RuntimeType[] typeContext = null;
2244 RuntimeType[] methodContext = null;
2245 RuntimeType[] genericParamters = null;
2247 if (definition is Type)
2249 RuntimeType genericTypeDefinition = (RuntimeType)definition;
2250 genericParamters = genericTypeDefinition.GetGenericArgumentsInternal();
2251 typeContext = genericArguments;
2253 else
2255 RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition;
2256 genericParamters = genericMethodDefinition.GetGenericArgumentsInternal();
2257 methodContext = genericArguments;
2259 RuntimeType declaringType = (RuntimeType)genericMethodDefinition.DeclaringType;
2260 if (declaringType != null)
2262 typeContext = declaringType.GetTypeHandleInternal().GetInstantiationInternal();
2266 for (int i = 0; i < genericArguments.Length; i++)
2268 Type genericArgument = genericArguments[i];
2269 Type genericParameter = genericParamters[i];
2271 if (!RuntimeTypeHandle.SatisfiesConstraints(genericParameter.GetTypeHandleInternal().GetTypeChecked(),
2272 typeContext, methodContext, genericArgument.GetTypeHandleInternal().GetTypeChecked()))
2274 throw new ArgumentException(
2275 Environment.GetResourceString("Argument_GenConstraintViolation",
2276 i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
2280 #endif
2281 private static void SplitName(string fullname, out string name, out string ns)
2283 name = null;
2284 ns = null;
2286 if (fullname == null)
2287 return;
2289 // Get namespace
2290 int nsDelimiter = fullname.LastIndexOf(".", StringComparison.Ordinal);
2291 if (nsDelimiter != -1 )
2293 ns = fullname.Substring(0, nsDelimiter);
2294 int nameLength = fullname.Length - ns.Length - 1;
2295 if (nameLength != 0)
2296 name = fullname.Substring(nsDelimiter + 1, nameLength);
2297 else
2298 name = "";
2299 Contract.Assert(fullname.Equals(ns + "." + name));
2301 else
2303 name = fullname;
2307 #endregion
2309 #region Filters
2310 internal static BindingFlags FilterPreCalculate(bool isPublic, bool isInherited, bool isStatic)
2312 BindingFlags bindingFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
2314 if (isInherited)
2316 // We arrange things so the DeclaredOnly flag means "include inherited members"
2317 bindingFlags |= BindingFlags.DeclaredOnly;
2319 if (isStatic)
2321 bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
2323 else
2325 bindingFlags |= BindingFlags.Instance;
2328 else
2330 if (isStatic)
2332 bindingFlags |= BindingFlags.Static;
2334 else
2336 bindingFlags |= BindingFlags.Instance;
2340 return bindingFlags;
2343 // Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
2344 private static void FilterHelper(
2345 BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup,
2346 out bool ignoreCase, out MemberListType listType)
2348 prefixLookup = false;
2349 ignoreCase = false;
2351 if (name != null)
2353 if ((bindingFlags & BindingFlags.IgnoreCase) != 0)
2355 name = name.ToLower(CultureInfo.InvariantCulture);
2356 ignoreCase = true;
2357 listType = MemberListType.CaseInsensitive;
2359 else
2361 listType = MemberListType.CaseSensitive;
2364 if (allowPrefixLookup && name.EndsWith("*", StringComparison.Ordinal))
2366 // We set prefixLookup to true if name ends with a "*".
2367 // We will also set listType to All so that all members are included in
2368 // the candidates which are later filtered by FilterApplyPrefixLookup.
2369 name = name.Substring(0, name.Length - 1);
2370 prefixLookup = true;
2371 listType = MemberListType.All;
2374 else
2376 listType = MemberListType.All;
2380 // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported.
2381 private static void FilterHelper(BindingFlags bindingFlags, ref string name, out bool ignoreCase, out MemberListType listType)
2383 bool prefixLookup;
2384 FilterHelper(bindingFlags, ref name, false, out prefixLookup, out ignoreCase, out listType);
2387 // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true.
2388 // Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
2389 private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase)
2391 Contract.Assert(name != null);
2393 if (ignoreCase)
2395 if (!memberInfo.Name.StartsWith(name, StringComparison.OrdinalIgnoreCase))
2396 return false;
2398 else
2400 if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
2401 return false;
2404 return true;
2408 // Used by FilterApplyType to perform all the filtering based on name and BindingFlags
2409 private static bool FilterApplyBase(
2410 MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
2411 string name, bool prefixLookup)
2413 #region Preconditions
2414 Contract.Requires(memberInfo != null);
2415 Contract.Requires(name == null || (bindingFlags & BindingFlags.IgnoreCase) == 0 || (name.ToLower(CultureInfo.InvariantCulture).Equals(name)));
2416 #endregion
2418 #region Filter by Public & Private
2419 if (isPublic)
2421 if ((bindingFlags & BindingFlags.Public) == 0)
2422 return false;
2424 else
2426 if ((bindingFlags & BindingFlags.NonPublic) == 0)
2427 return false;
2429 #endregion
2431 bool isInherited = !Object.ReferenceEquals(memberInfo.DeclaringType, memberInfo.ReflectedType);
2433 #region Filter by DeclaredOnly
2434 if ((bindingFlags & BindingFlags.DeclaredOnly) != 0 && isInherited)
2435 return false;
2436 #endregion
2438 #region Filter by Static & Instance
2439 if (memberInfo.MemberType != MemberTypes.TypeInfo &&
2440 memberInfo.MemberType != MemberTypes.NestedType)
2442 if (isStatic)
2444 if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0 && isInherited)
2445 return false;
2447 if ((bindingFlags & BindingFlags.Static) == 0)
2448 return false;
2450 else
2452 if ((bindingFlags & BindingFlags.Instance) == 0)
2453 return false;
2456 #endregion
2458 #region Filter by name wrt prefixLookup and implicitly by case sensitivity
2459 if (prefixLookup == true)
2461 if (!FilterApplyPrefixLookup(memberInfo, name, (bindingFlags & BindingFlags.IgnoreCase) != 0))
2462 return false;
2464 #endregion
2466 #region Asymmetries
2467 // @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned
2468 // iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
2469 if (((bindingFlags & BindingFlags.DeclaredOnly) == 0) && // DeclaredOnly not present
2470 isInherited && // Is inherited Member
2472 (isNonProtectedInternal) && // Is non-protected internal member
2473 ((bindingFlags & BindingFlags.NonPublic) != 0) && // BindingFlag.NonPublic present
2475 (!isStatic) && // Is instance member
2476 ((bindingFlags & BindingFlags.Instance) != 0)) // BindingFlag.Instance present
2478 MethodInfo methodInfo = memberInfo as MethodInfo;
2480 if (methodInfo == null)
2481 return false;
2483 if (!methodInfo.IsVirtual && !methodInfo.IsAbstract)
2484 return false;
2486 #endregion
2488 return true;
2492 // Used by GetInterface and GetNestedType(s) which don't need parameter type filtering.
2493 private static bool FilterApplyType(
2494 Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns)
2496 Contract.Requires((object)type != null);
2497 Contract.Assert(type is RuntimeType);
2499 bool isPublic = type.IsNestedPublic || type.IsPublic;
2500 bool isStatic = false;
2502 if (!RuntimeType.FilterApplyBase(type, bindingFlags, isPublic, type.IsNestedAssembly, isStatic, name, prefixLookup))
2503 return false;
2505 if (ns != null && ns != type.Namespace)
2506 return false;
2508 return true;
2512 private static bool FilterApplyMethodInfo(
2513 RuntimeMethodInfo method, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2515 // Optimization: Pre-Calculate the method binding flags to avoid casting.
2516 return FilterApplyMethodBase(method, method.BindingFlags, bindingFlags, callConv, argumentTypes);
2519 private static bool FilterApplyConstructorInfo(
2520 RuntimeConstructorInfo constructor, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2522 // Optimization: Pre-Calculate the method binding flags to avoid casting.
2523 return FilterApplyMethodBase(constructor, constructor.BindingFlags, bindingFlags, callConv, argumentTypes);
2526 // Used by GetMethodCandidates/GetConstructorCandidates, InvokeMember, and CreateInstanceImpl to perform the necessary filtering.
2527 // Should only be called by FilterApplyMethodInfo and FilterApplyConstructorInfo.
2528 private static bool FilterApplyMethodBase(
2529 MethodBase methodBase, BindingFlags methodFlags, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2531 Contract.Requires(methodBase != null);
2533 bindingFlags ^= BindingFlags.DeclaredOnly;
2534 #if !MONO
2535 #region Apply Base Filter
2536 if ((bindingFlags & methodFlags) != methodFlags)
2537 return false;
2538 #endregion
2539 #endif
2540 #region Check CallingConvention
2541 if ((callConv & CallingConventions.Any) == 0)
2543 if ((callConv & CallingConventions.VarArgs) != 0 &&
2544 (methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2545 return false;
2547 if ((callConv & CallingConventions.Standard) != 0 &&
2548 (methodBase.CallingConvention & CallingConventions.Standard) == 0)
2549 return false;
2551 #endregion
2553 #region If argumentTypes supplied
2554 if (argumentTypes != null)
2556 ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy();
2558 if (argumentTypes.Length != parameterInfos.Length)
2560 #region Invoke Member, Get\Set & Create Instance specific case
2561 // If the number of supplied arguments differs than the number in the signature AND
2562 // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
2563 if ((bindingFlags &
2564 (BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
2565 return false;
2567 bool testForParamArray = false;
2568 bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
2570 if (excessSuppliedArguments)
2571 { // more supplied arguments than parameters, additional arguments could be vararg
2572 #region Varargs
2573 // If method is not vararg, additional arguments can not be passed as vararg
2574 if ((methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2576 testForParamArray = true;
2578 else
2580 // If Binding flags did not include varargs we would have filtered this vararg method.
2581 // This Invariant established during callConv check.
2582 Contract.Assert((callConv & CallingConventions.VarArgs) != 0);
2584 #endregion
2586 else
2587 {// fewer supplied arguments than parameters, missing arguments could be optional
2588 #region OptionalParamBinding
2589 if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
2591 testForParamArray = true;
2593 else
2595 // From our existing code, our policy here is that if a parameterInfo
2596 // is optional then all subsequent parameterInfos shall be optional.
2598 // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
2599 if (!parameterInfos[argumentTypes.Length].IsOptional)
2600 testForParamArray = true;
2602 #endregion
2605 #region ParamArray
2606 if (testForParamArray)
2608 if (parameterInfos.Length == 0)
2609 return false;
2611 // The last argument of the signature could be a param array.
2612 bool shortByMoreThanOneSuppliedArgument = argumentTypes.Length < parameterInfos.Length - 1;
2614 if (shortByMoreThanOneSuppliedArgument)
2615 return false;
2617 ParameterInfo lastParameter = parameterInfos[parameterInfos.Length - 1];
2619 if (!lastParameter.ParameterType.IsArray)
2620 return false;
2622 if (!lastParameter.IsDefined(typeof(ParamArrayAttribute), false))
2623 return false;
2625 #endregion
2627 #endregion
2629 else
2631 #region Exact Binding
2632 if ((bindingFlags & BindingFlags.ExactBinding) != 0)
2634 // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
2635 // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
2636 // all the rest of this to the binder too? Further, what other semanitc would the binder
2637 // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance
2638 // in this if statement? That's just InvokeMethod with a constructor, right?
2639 if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
2641 for(int i = 0; i < parameterInfos.Length; i ++)
2643 // a null argument type implies a null arg which is always a perfect match
2644 #if MONO
2645 if ((object)argumentTypes[i] != null && !argumentTypes[i].MatchesParameterTypeExactly(parameterInfos[i]))
2646 #else
2647 if ((object)argumentTypes[i] != null && !Object.ReferenceEquals(parameterInfos[i].ParameterType, argumentTypes[i]))
2648 #endif
2649 return false;
2653 #endregion
2656 #endregion
2658 return true;
2661 #endregion
2663 #endregion
2665 #region Private Data Members
2666 #if !MONO
2667 private object m_keepalive; // This will be filled with a LoaderAllocator reference when this RuntimeType represents a collectible type
2668 private IntPtr m_cache;
2669 internal IntPtr m_handle;
2670 #endif
2671 #if FEATURE_APPX
2672 private INVOCATION_FLAGS m_invocationFlags;
2674 internal bool IsNonW8PFrameworkAPI()
2676 if (IsGenericParameter)
2677 return false;
2679 if (HasElementType)
2680 return ((RuntimeType)GetElementType()).IsNonW8PFrameworkAPI();
2682 if (IsSimpleTypeNonW8PFrameworkAPI())
2683 return true;
2685 if (IsGenericType && !IsGenericTypeDefinition)
2687 foreach (Type t in GetGenericArguments())
2689 if (((RuntimeType)t).IsNonW8PFrameworkAPI())
2690 return true;
2694 return false;
2697 private bool IsSimpleTypeNonW8PFrameworkAPI()
2699 RuntimeAssembly rtAssembly = GetRuntimeAssembly();
2700 if (rtAssembly.IsFrameworkAssembly())
2702 int ctorToken = rtAssembly.InvocableAttributeCtorToken;
2703 if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
2704 !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
2705 return true;
2708 return false;
2711 internal INVOCATION_FLAGS InvocationFlags
2715 if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
2717 INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
2719 if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
2720 invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
2722 m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
2725 return m_invocationFlags;
2728 #endif // FEATURE_APPX
2730 internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);
2731 internal static readonly RuntimeType EnumType = (RuntimeType)typeof(System.Enum);
2733 private static readonly RuntimeType ObjectType = (RuntimeType)typeof(System.Object);
2734 private static readonly RuntimeType StringType = (RuntimeType)typeof(System.String);
2735 private static readonly RuntimeType DelegateType = (RuntimeType)typeof(System.Delegate);
2737 private static Type[] s_SICtorParamTypes;
2738 #endregion
2740 #region Constructor
2741 internal RuntimeType() { throw new NotSupportedException(); }
2742 #endregion
2744 #region Private\Internal Members
2745 #if !MONO
2746 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
2747 internal override bool CacheEquals(object o)
2749 RuntimeType m = o as RuntimeType;
2751 if (m == null)
2752 return false;
2754 return m.m_handle.Equals(m_handle);
2757 private RuntimeTypeCache Cache
2759 [System.Security.SecuritySafeCritical] // auto-generated
2760 [ResourceExposure(ResourceScope.None)]
2761 [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
2764 if (m_cache.IsNull())
2766 IntPtr newgcHandle = new RuntimeTypeHandle(this).GetGCHandle(GCHandleType.WeakTrackResurrection);
2767 IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0);
2768 // Leak the handle if the type is collectible. It will be reclaimed when
2769 // the type goes away.
2770 if (!gcHandle.IsNull() && !IsCollectible())
2771 GCHandle.InternalFree(newgcHandle);
2774 RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
2775 if (cache == null)
2777 cache = new RuntimeTypeCache(this);
2778 RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache;
2779 if (existingCache != null)
2780 cache = existingCache;
2783 Contract.Assert(cache != null);
2784 return cache;
2787 #endif
2788 internal bool IsSpecialSerializableType()
2790 RuntimeType rt = this;
2793 // In all sane cases we only need to compare the direct level base type with
2794 // System.Enum and System.MulticastDelegate. However, a generic argument can
2795 // have a base type constraint that is Delegate or even a real delegate type.
2796 // Let's maintain compatibility and return true for them.
2797 if (rt == RuntimeType.DelegateType || rt == RuntimeType.EnumType)
2798 return true;
2800 rt = rt.GetBaseType();
2801 } while (rt != null);
2803 return false;
2805 #if !MONO
2806 private string GetDefaultMemberName()
2808 return Cache.GetDefaultMemberName();
2811 #if !FEATURE_CORECLR
2812 internal RuntimeConstructorInfo GetSerializationCtor()
2814 return Cache.GetSerializationCtor();
2816 #endif
2817 #endif
2818 #endregion
2820 #region Type Overrides
2822 #region Get XXXInfo Candidates
2823 private ListBuilder<MethodInfo> GetMethodCandidates(
2824 String name, BindingFlags bindingAttr, CallingConventions callConv,
2825 Type[] types, int genericParamCount, bool allowPrefixLookup)
2827 bool prefixLookup, ignoreCase;
2828 MemberListType listType;
2829 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2831 #if MONO
2832 RuntimeMethodInfo[] cache = GetMethodsByName (name, bindingAttr, listType, this);
2833 #else
2834 RuntimeMethodInfo[] cache = Cache.GetMethodList(listType, name);
2835 #endif
2836 ListBuilder<MethodInfo> candidates = new ListBuilder<MethodInfo>(cache.Length);
2838 for (int i = 0; i < cache.Length; i++)
2840 RuntimeMethodInfo methodInfo = cache[i];
2841 if (genericParamCount != -1) {
2842 bool is_generic = methodInfo.IsGenericMethod;
2843 if (genericParamCount == 0 && is_generic)
2844 continue;
2845 else if (genericParamCount > 0 && !is_generic)
2846 continue;
2847 var args = methodInfo.GetGenericArguments ();
2848 if (args.Length != genericParamCount)
2849 continue;
2851 if (FilterApplyMethodInfo(methodInfo, bindingAttr, callConv, types) &&
2852 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase)))
2854 candidates.Add(methodInfo);
2858 return candidates;
2861 private ListBuilder<ConstructorInfo> GetConstructorCandidates(
2862 string name, BindingFlags bindingAttr, CallingConventions callConv,
2863 Type[] types, bool allowPrefixLookup)
2865 bool prefixLookup, ignoreCase;
2866 MemberListType listType;
2867 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2869 #if MONO
2870 if (!string.IsNullOrEmpty (name) && name != ConstructorInfo.ConstructorName && name != ConstructorInfo.TypeConstructorName)
2871 return new ListBuilder<ConstructorInfo> (0);
2872 RuntimeConstructorInfo[] cache = GetConstructors_internal (bindingAttr, this);
2873 #else
2874 RuntimeConstructorInfo[] cache = Cache.GetConstructorList(listType, name);
2875 #endif
2876 ListBuilder<ConstructorInfo> candidates = new ListBuilder<ConstructorInfo>(cache.Length);
2877 for (int i = 0; i < cache.Length; i++)
2879 RuntimeConstructorInfo constructorInfo = cache[i];
2880 if (FilterApplyConstructorInfo(constructorInfo, bindingAttr, callConv, types) &&
2881 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase)))
2883 candidates.Add(constructorInfo);
2887 return candidates;
2891 private ListBuilder<PropertyInfo> GetPropertyCandidates(
2892 String name, BindingFlags bindingAttr, Type[] types, bool allowPrefixLookup)
2894 bool prefixLookup, ignoreCase;
2895 MemberListType listType;
2896 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2898 #if MONO
2899 RuntimePropertyInfo[] cache = GetPropertiesByName (name, bindingAttr, listType, this);
2900 #else
2901 #if FEATURE_LEGACYNETCF
2902 // Dev11 466969 quirk
2903 IReadOnlyList<RuntimePropertyInfo> ambiguousProperties = null;
2904 RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name, out ambiguousProperties);
2905 #else
2906 RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name);
2907 #endif
2908 #endif
2909 bindingAttr ^= BindingFlags.DeclaredOnly;
2911 ListBuilder<PropertyInfo> candidates = new ListBuilder<PropertyInfo>(cache.Length);
2912 for (int i = 0; i < cache.Length; i++)
2914 RuntimePropertyInfo propertyInfo = cache[i];
2915 if ((bindingAttr & propertyInfo.BindingFlags) == propertyInfo.BindingFlags &&
2916 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(propertyInfo, name, ignoreCase)) &&
2917 (types == null || (propertyInfo.GetIndexParameters().Length == types.Length)))
2919 candidates.Add(propertyInfo);
2923 #if FEATURE_LEGACYNETCF
2924 // Dev11 466969 quirk
2925 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 &&
2926 candidates.Count > 1 &&
2927 ambiguousProperties != null &&
2928 ambiguousProperties.Count > 0)
2930 return PruneAmbiguousProperties(candidates, ambiguousProperties);
2932 #endif
2934 return candidates;
2937 #if FEATURE_LEGACYNETCF
2938 private ListBuilder<PropertyInfo> PruneAmbiguousProperties(ListBuilder<PropertyInfo> candidates, IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
2940 Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
2941 Contract.Assert(candidates.Count > 1);
2942 Contract.Assert(ambiguousProperties != null && ambiguousProperties.Count > 0);
2944 ListBuilder<PropertyInfo> newCandidates = candidates;
2946 // Dev11 466969 quirk
2947 // NetCF reflection will differentiate properties by sig and by accessibility.
2948 // Consider the following:
2950 // class FooBase
2951 // {
2952 // public int Prop { get; set; }
2953 // }
2955 // class FooDerived : FooBase
2956 // {
2957 // private int Prop { get; set; }
2958 // }
2960 // In Mango one can reflect on FooDerived for property "Prop" with *Public*
2961 // binding flags and get an answer. On desktop CLR/CoreCLR you get back null
2962 // since FooBase.Prop is considered a duplicate and thus removed from the
2963 // list of candidate properties. To make this distinction the method
2964 // RuntimePropertyInfo.HasMatchingAccessibility() was added.
2966 // There is a wrinkle here though, when reflecting on FooDerived for
2967 // property "Prop" with Public and NonPublic binding flags the answer
2968 // will always be the most-derived type, so FooDerived in this example.
2969 // The purpose of PruneAmbiguousProperties() is to apply this invariant.
2972 int countRemoved = 0;
2974 lock (ambiguousProperties)
2976 for (int outerIndex = 0; outerIndex < ambiguousProperties.Count; ++outerIndex)
2978 for (int innerIndex = 0; innerIndex < candidates.Count; ++innerIndex)
2980 if (candidates[innerIndex] != null &&
2981 candidates[innerIndex] == ambiguousProperties[outerIndex])
2983 candidates[innerIndex] = null;
2984 ++countRemoved;
2990 // should have only gone down this code path because we knew
2991 // that at least one ambiguous property needed to be pruned.
2992 Contract.Assert(countRemoved > 0);
2994 if (countRemoved > 0)
2996 newCandidates = new ListBuilder<PropertyInfo>(candidates.Count - countRemoved);
2997 for (int index = 0; index < candidates.Count; ++index)
2999 if (candidates[index] != null)
3000 newCandidates.Add(candidates[index]);
3003 Contract.Assert(newCandidates.Count == (candidates.Count - countRemoved));
3006 return newCandidates;
3008 #endif
3010 private ListBuilder<EventInfo> GetEventCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
3012 bool prefixLookup, ignoreCase;
3013 MemberListType listType;
3014 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3016 #if MONO
3017 RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, listType, this);
3018 #else
3019 RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3020 #endif
3021 bindingAttr ^= BindingFlags.DeclaredOnly;
3023 ListBuilder<EventInfo> candidates = new ListBuilder<EventInfo>(cache.Length);
3024 for (int i = 0; i < cache.Length; i++)
3026 RuntimeEventInfo eventInfo = cache[i];
3027 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags &&
3028 (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
3030 candidates.Add(eventInfo);
3034 return candidates;
3037 private ListBuilder<FieldInfo> GetFieldCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
3039 bool prefixLookup, ignoreCase;
3040 MemberListType listType;
3041 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3043 #if MONO
3044 RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, listType, this);
3045 #else
3046 RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3047 #endif
3048 bindingAttr ^= BindingFlags.DeclaredOnly;
3050 ListBuilder<FieldInfo> candidates = new ListBuilder<FieldInfo>(cache.Length);
3051 for (int i = 0; i < cache.Length; i++)
3053 RuntimeFieldInfo fieldInfo = cache[i];
3054 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
3055 (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
3057 candidates.Add(fieldInfo);
3061 return candidates;
3064 private ListBuilder<Type> GetNestedTypeCandidates(String fullname, BindingFlags bindingAttr, bool allowPrefixLookup)
3066 bool prefixLookup, ignoreCase;
3067 bindingAttr &= ~BindingFlags.Static;
3068 string name, ns;
3069 MemberListType listType;
3070 SplitName(fullname, out name, out ns);
3071 RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3073 #if MONO
3074 RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr, listType);
3075 #else
3076 RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3077 #endif
3078 ListBuilder<Type> candidates = new ListBuilder<Type>(cache.Length);
3079 for (int i = 0; i < cache.Length; i++)
3081 RuntimeType nestedClass = cache[i];
3082 if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
3084 candidates.Add(nestedClass);
3088 return candidates;
3091 #endregion
3093 #region Get All XXXInfos
3094 public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
3096 return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false).ToArray();
3099 [System.Runtime.InteropServices.ComVisible(true)]
3100 public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
3102 return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
3105 public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
3107 return GetPropertyCandidates(null, bindingAttr, null, false).ToArray();
3110 public override EventInfo[] GetEvents(BindingFlags bindingAttr)
3112 return GetEventCandidates(null, bindingAttr, false).ToArray();
3115 public override FieldInfo[] GetFields(BindingFlags bindingAttr)
3117 return GetFieldCandidates(null, bindingAttr, false).ToArray();
3119 #if !MONO
3120 [System.Security.SecuritySafeCritical] // auto-generated
3121 public override Type[] GetInterfaces()
3123 RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
3124 Type[] interfaces = new Type[candidates.Length];
3125 for (int i = 0; i < candidates.Length; i++)
3126 JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
3128 return interfaces;
3130 #endif
3131 public override Type[] GetNestedTypes(BindingFlags bindingAttr)
3133 return GetNestedTypeCandidates(null, bindingAttr, false).ToArray();
3136 public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
3138 ListBuilder<MethodInfo> methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false);
3139 ListBuilder<ConstructorInfo> constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false);
3140 ListBuilder<PropertyInfo> properties = GetPropertyCandidates(null, bindingAttr, null, false);
3141 ListBuilder<EventInfo> events = GetEventCandidates(null, bindingAttr, false);
3142 ListBuilder<FieldInfo> fields = GetFieldCandidates(null, bindingAttr, false);
3143 ListBuilder<Type> nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false);
3144 // Interfaces are excluded from the result of GetMembers
3146 MemberInfo[] members = new MemberInfo[
3147 methods.Count +
3148 constructors.Count +
3149 properties.Count +
3150 events.Count +
3151 fields.Count +
3152 nestedTypes.Count];
3154 int i = 0;
3155 methods.CopyTo(members, i); i += methods.Count;
3156 constructors.CopyTo(members, i); i += constructors.Count;
3157 properties.CopyTo(members, i); i += properties.Count;
3158 events.CopyTo(members, i); i += events.Count;
3159 fields.CopyTo(members, i); i += fields.Count;
3160 nestedTypes.CopyTo(members, i); i += nestedTypes.Count;
3161 Contract.Assert(i == members.Length);
3163 return members;
3165 #if !MONO
3166 [System.Security.SecuritySafeCritical] // auto-generated
3167 public override InterfaceMapping GetInterfaceMap(Type ifaceType)
3169 if (IsGenericParameter)
3170 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
3172 if ((object)ifaceType == null)
3173 throw new ArgumentNullException("ifaceType");
3174 Contract.EndContractBlock();
3176 RuntimeType ifaceRtType = ifaceType as RuntimeType;
3178 if (ifaceRtType == null)
3179 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
3181 RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
3183 GetTypeHandleInternal().VerifyInterfaceIsImplemented(ifaceRtTypeHandle);
3184 Contract.Assert(ifaceType.IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
3185 Contract.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
3187 // SZArrays implement the methods on IList`1, IEnumerable`1, and ICollection`1 with
3188 // SZArrayHelper and some runtime magic. We don't have accurate interface maps for them.
3189 if (IsSzArray && ifaceType.IsGenericType)
3190 throw new ArgumentException(Environment.GetResourceString("Argument_ArrayGetInterfaceMap"));
3192 int ifaceInstanceMethodCount = RuntimeTypeHandle.GetNumVirtuals(ifaceRtType);
3194 InterfaceMapping im;
3195 im.InterfaceType = ifaceType;
3196 im.TargetType = this;
3197 im.InterfaceMethods = new MethodInfo[ifaceInstanceMethodCount];
3198 im.TargetMethods = new MethodInfo[ifaceInstanceMethodCount];
3200 for (int i = 0; i < ifaceInstanceMethodCount; i++)
3202 RuntimeMethodHandleInternal ifaceRtMethodHandle = RuntimeTypeHandle.GetMethodAt(ifaceRtType, i);
3204 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3205 MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtType, ifaceRtMethodHandle);
3206 Contract.Assert(ifaceMethodBase is RuntimeMethodInfo);
3207 im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase;
3209 // If the slot is -1, then virtual stub dispatch is active.
3210 int slot = GetTypeHandleInternal().GetInterfaceMethodImplementationSlot(ifaceRtTypeHandle, ifaceRtMethodHandle);
3212 if (slot == -1) continue;
3214 RuntimeMethodHandleInternal classRtMethodHandle = RuntimeTypeHandle.GetMethodAt(this, slot);
3216 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3217 MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(this, classRtMethodHandle);
3218 // a class may not implement all the methods of an interface (abstract class) so null is a valid value
3219 Contract.Assert(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
3220 im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase;
3223 return im;
3225 #endif
3226 #endregion
3228 #if NETCORE
3229 protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
3231 return GetMethodImpl (name, -1, bindingAttr, binder, callConvention, types, modifiers);
3234 protected override MethodInfo GetMethodImpl(String name, int genericParamCount,
3235 BindingFlags bindingAttr, Binder binder, CallingConventions callConv,
3236 Type[] types, ParameterModifier[] modifiers)
3238 ListBuilder<MethodInfo> candidates = GetMethodCandidates(name, bindingAttr, callConv, types, genericParamCount, false);
3239 if (candidates.Count == 0)
3240 return null;
3242 if (types == null || types.Length == 0)
3244 MethodInfo firstCandidate = candidates[0];
3246 if (candidates.Count == 1)
3248 return firstCandidate;
3250 else if (types == null)
3252 for (int j = 1; j < candidates.Count; j++)
3254 MethodInfo methodInfo = candidates[j];
3255 if (!System.DefaultBinder.CompareMethodSig (methodInfo, firstCandidate))
3256 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3259 // All the methods have the exact same name and sig so return the most derived one.
3260 return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo;
3264 if (binder == null)
3265 binder = DefaultBinder;
3267 return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;
3269 #endif
3271 protected override ConstructorInfo GetConstructorImpl(
3272 BindingFlags bindingAttr, Binder binder, CallingConventions callConvention,
3273 Type[] types, ParameterModifier[] modifiers)
3275 ListBuilder<ConstructorInfo> candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false);
3277 if (candidates.Count == 0)
3278 return null;
3280 if (types.Length == 0 && candidates.Count == 1)
3282 ConstructorInfo firstCandidate = candidates[0];
3284 ParameterInfo[] parameters = firstCandidate.GetParametersNoCopy();
3285 if (parameters == null || parameters.Length == 0)
3287 return firstCandidate;
3291 if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3292 return System.DefaultBinder.ExactBinding(candidates.ToArray(), types, modifiers) as ConstructorInfo;
3294 if (binder == null)
3295 binder = DefaultBinder;
3297 return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo;
3301 protected override PropertyInfo GetPropertyImpl(
3302 String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
3304 if (name == null) throw new ArgumentNullException();
3305 Contract.EndContractBlock();
3307 ListBuilder<PropertyInfo> candidates = GetPropertyCandidates(name, bindingAttr, types, false);
3309 if (candidates.Count == 0)
3310 return null;
3312 if (types == null || types.Length == 0)
3314 // no arguments
3315 if (candidates.Count == 1)
3317 PropertyInfo firstCandidate = candidates[0];
3319 if ((object)returnType != null && !returnType.IsEquivalentTo(firstCandidate.PropertyType))
3320 return null;
3322 return firstCandidate;
3324 else
3326 if ((object)returnType == null)
3327 // if we are here we have no args or property type to select over and we have more than one property with that name
3328 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3332 if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3333 return System.DefaultBinder.ExactPropertyBinding(candidates.ToArray(), returnType, types, modifiers);
3335 if (binder == null)
3336 binder = DefaultBinder;
3338 return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
3341 public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
3343 if (name == null) throw new ArgumentNullException();
3344 Contract.EndContractBlock();
3346 bool ignoreCase;
3347 MemberListType listType;
3348 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3350 #if MONO
3351 RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, listType, this);
3352 #else
3353 RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3354 #endif
3355 EventInfo match = null;
3357 bindingAttr ^= BindingFlags.DeclaredOnly;
3359 for (int i = 0; i < cache.Length; i++)
3361 RuntimeEventInfo eventInfo = cache[i];
3362 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags)
3364 if (match != null)
3365 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3367 match = eventInfo;
3371 return match;
3374 public override FieldInfo GetField(String name, BindingFlags bindingAttr)
3376 if (name == null) throw new ArgumentNullException();
3377 Contract.EndContractBlock();
3379 bool ignoreCase;
3380 MemberListType listType;
3381 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3383 #if MONO
3384 RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, listType, this);
3385 #else
3386 RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3387 #endif
3388 FieldInfo match = null;
3390 bindingAttr ^= BindingFlags.DeclaredOnly;
3391 bool multipleStaticFieldMatches = false;
3393 for (int i = 0; i < cache.Length; i++)
3395 RuntimeFieldInfo fieldInfo = cache[i];
3396 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
3398 if (match != null)
3400 if (Object.ReferenceEquals(fieldInfo.DeclaringType, match.DeclaringType))
3401 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3403 if ((match.DeclaringType.IsInterface == true) && (fieldInfo.DeclaringType.IsInterface == true))
3404 multipleStaticFieldMatches = true;
3407 if (match == null || fieldInfo.DeclaringType.IsSubclassOf(match.DeclaringType) || match.DeclaringType.IsInterface)
3408 match = fieldInfo;
3412 if (multipleStaticFieldMatches && match.DeclaringType.IsInterface)
3413 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3415 return match;
3418 public override Type GetInterface(String fullname, bool ignoreCase)
3420 if (fullname == null) throw new ArgumentNullException();
3421 Contract.EndContractBlock();
3423 BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic;
3425 bindingAttr &= ~BindingFlags.Static;
3427 if (ignoreCase)
3428 bindingAttr |= BindingFlags.IgnoreCase;
3430 string name, ns;
3431 MemberListType listType;
3432 SplitName(fullname, out name, out ns);
3433 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3435 #if MONO
3436 List<RuntimeType> list = null;
3437 var nameComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
3438 foreach (RuntimeType t in GetInterfaces ()) {
3440 if (!String.Equals(t.Name, name, nameComparison)) {
3441 continue;
3444 if (list == null)
3445 list = new List<RuntimeType> (2);
3447 list.Add (t);
3450 if (list == null)
3451 return null;
3453 var cache = list.ToArray ();
3454 #else
3455 RuntimeType[] cache = Cache.GetInterfaceList(listType, name);
3456 #endif
3457 RuntimeType match = null;
3459 for (int i = 0; i < cache.Length; i++)
3461 RuntimeType iface = cache[i];
3462 if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
3464 if (match != null)
3465 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3467 match = iface;
3471 return match;
3474 public override Type GetNestedType(String fullname, BindingFlags bindingAttr)
3476 if (fullname == null) throw new ArgumentNullException();
3477 Contract.EndContractBlock();
3479 bool ignoreCase;
3480 bindingAttr &= ~BindingFlags.Static;
3481 string name, ns;
3482 MemberListType listType;
3483 SplitName(fullname, out name, out ns);
3484 RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3485 #if MONO
3486 RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr, listType);
3487 #else
3488 RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3489 #endif
3490 RuntimeType match = null;
3492 for (int i = 0; i < cache.Length; i++)
3494 RuntimeType nestedType = cache[i];
3495 if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
3497 if (match != null)
3498 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3500 match = nestedType;
3504 return match;
3507 public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
3509 if (name == null) throw new ArgumentNullException();
3510 Contract.EndContractBlock();
3512 ListBuilder<MethodInfo> methods = new ListBuilder<MethodInfo>();
3513 ListBuilder<ConstructorInfo> constructors = new ListBuilder<ConstructorInfo>();
3514 ListBuilder<PropertyInfo> properties = new ListBuilder<PropertyInfo>();
3515 ListBuilder<EventInfo> events = new ListBuilder<EventInfo>();
3516 ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>();
3517 ListBuilder<Type> nestedTypes = new ListBuilder<Type>();
3519 int totalCount = 0;
3521 // Methods
3522 if ((type & MemberTypes.Method) != 0)
3524 methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, -1, true);
3525 if (type == MemberTypes.Method)
3526 return methods.ToArray();
3527 totalCount += methods.Count;
3530 // Constructors
3531 if ((type & MemberTypes.Constructor) != 0)
3533 constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true);
3534 if (type == MemberTypes.Constructor)
3535 return constructors.ToArray();
3536 totalCount += constructors.Count;
3539 // Properties
3540 if ((type & MemberTypes.Property) != 0)
3542 properties = GetPropertyCandidates(name, bindingAttr, null, true);
3543 if (type == MemberTypes.Property)
3544 return properties.ToArray();
3545 totalCount += properties.Count;
3548 // Events
3549 if ((type & MemberTypes.Event) != 0)
3551 events = GetEventCandidates(name, bindingAttr, true);
3552 if (type == MemberTypes.Event)
3553 return events.ToArray();
3554 totalCount += events.Count;
3557 // Fields
3558 if ((type & MemberTypes.Field) != 0)
3560 fields = GetFieldCandidates(name, bindingAttr, true);
3561 if (type == MemberTypes.Field)
3562 return fields.ToArray();
3563 totalCount += fields.Count;
3566 // NestedTypes
3567 if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
3569 nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);
3570 if (type == MemberTypes.NestedType || type == MemberTypes.TypeInfo)
3571 return nestedTypes.ToArray();
3572 totalCount += nestedTypes.Count;
3575 MemberInfo[] compressMembers = (type == (MemberTypes.Method | MemberTypes.Constructor)) ?
3576 new MethodBase[totalCount] : new MemberInfo[totalCount];
3578 int i = 0;
3579 methods.CopyTo(compressMembers, i); i += methods.Count;
3580 constructors.CopyTo(compressMembers, i); i += constructors.Count;
3581 properties.CopyTo(compressMembers, i); i += properties.Count;
3582 events.CopyTo(compressMembers, i); i += events.Count;
3583 fields.CopyTo(compressMembers, i); i += fields.Count;
3584 nestedTypes.CopyTo(compressMembers, i); i += nestedTypes.Count;
3585 Contract.Assert(i == compressMembers.Length);
3587 return compressMembers;
3589 #endregion
3591 #region Identity
3593 public override Module Module
3597 return GetRuntimeModule();
3601 internal RuntimeModule GetRuntimeModule()
3603 return RuntimeTypeHandle.GetModule(this);
3606 public override Assembly Assembly
3608 get
3610 return GetRuntimeAssembly();
3614 internal RuntimeAssembly GetRuntimeAssembly()
3616 return RuntimeTypeHandle.GetAssembly(this);
3619 public override RuntimeTypeHandle TypeHandle
3621 get
3623 return new RuntimeTypeHandle(this);
3627 #if !NETCORE
3628 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
3629 internal sealed override RuntimeTypeHandle GetTypeHandleInternal()
3631 return new RuntimeTypeHandle(this);
3633 #endif
3635 #if !MONO
3636 [System.Security.SecuritySafeCritical]
3637 internal bool IsCollectible()
3639 return RuntimeTypeHandle.IsCollectible(GetTypeHandleInternal());
3642 [System.Security.SecuritySafeCritical] // auto-generated
3643 protected override TypeCode GetTypeCodeImpl()
3645 TypeCode typeCode = Cache.TypeCode;
3647 if (typeCode != TypeCode.Empty)
3648 return typeCode;
3650 CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this);
3651 switch (corElementType)
3653 case CorElementType.Boolean:
3654 typeCode = TypeCode.Boolean; break;
3655 case CorElementType.Char:
3656 typeCode = TypeCode.Char; break;
3657 case CorElementType.I1:
3658 typeCode = TypeCode.SByte; break;
3659 case CorElementType.U1:
3660 typeCode = TypeCode.Byte; break;
3661 case CorElementType.I2:
3662 typeCode = TypeCode.Int16; break;
3663 case CorElementType.U2:
3664 typeCode = TypeCode.UInt16; break;
3665 case CorElementType.I4:
3666 typeCode = TypeCode.Int32; break;
3667 case CorElementType.U4:
3668 typeCode = TypeCode.UInt32; break;
3669 case CorElementType.I8:
3670 typeCode = TypeCode.Int64; break;
3671 case CorElementType.U8:
3672 typeCode = TypeCode.UInt64; break;
3673 case CorElementType.R4:
3674 typeCode = TypeCode.Single; break;
3675 case CorElementType.R8:
3676 typeCode = TypeCode.Double; break;
3677 case CorElementType.String:
3678 typeCode = TypeCode.String; break;
3679 case CorElementType.ValueType:
3680 if (this == Convert.ConvertTypes[(int)TypeCode.Decimal])
3681 typeCode = TypeCode.Decimal;
3682 else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
3683 typeCode = TypeCode.DateTime;
3684 else if (this.IsEnum)
3685 typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
3686 else
3687 typeCode = TypeCode.Object;
3688 break;
3689 default:
3690 if (this == Convert.ConvertTypes[(int)TypeCode.DBNull])
3691 typeCode = TypeCode.DBNull;
3692 else if (this == Convert.ConvertTypes[(int)TypeCode.String])
3693 typeCode = TypeCode.String;
3694 else
3695 typeCode = TypeCode.Object;
3696 break;
3699 Cache.TypeCode = typeCode;
3701 return typeCode;
3704 public override MethodBase DeclaringMethod
3708 if (!IsGenericParameter)
3709 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
3710 Contract.EndContractBlock();
3712 IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this);
3714 if (declaringMethod == null)
3715 return null;
3717 return GetMethodBase(RuntimeMethodHandle.GetDeclaringType(declaringMethod), declaringMethod);
3720 #endif
3721 #endregion
3723 #region Hierarchy
3724 [System.Security.SecuritySafeCritical] // auto-generated
3725 public override bool IsInstanceOfType(Object o)
3727 return RuntimeTypeHandle.IsInstanceOfType(this, o);
3730 #if !MONO
3731 [System.Runtime.InteropServices.ComVisible(true)]
3732 [Pure]
3733 public override bool IsSubclassOf(Type type)
3735 if ((object)type == null)
3736 throw new ArgumentNullException("type");
3737 Contract.EndContractBlock();
3738 RuntimeType rtType = type as RuntimeType;
3739 if (rtType == null)
3740 return false;
3742 RuntimeType baseType = GetBaseType();
3744 while (baseType != null)
3746 if (baseType == rtType)
3747 return true;
3749 baseType = baseType.GetBaseType();
3752 // pretty much everything is a subclass of object, even interfaces
3753 // notice that interfaces are really odd because they do not have a BaseType
3754 // yet IsSubclassOf(typeof(object)) returns true
3755 if (rtType == RuntimeType.ObjectType && rtType != this)
3756 return true;
3758 return false;
3760 #endif
3762 public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
3763 if(typeInfo==null) return false;
3764 return IsAssignableFrom(typeInfo.AsType());
3767 public override bool IsAssignableFrom(Type c)
3769 if ((object)c == null)
3770 return false;
3772 if (Object.ReferenceEquals(c, this))
3773 return true;
3775 RuntimeType fromType = c.UnderlyingSystemType as RuntimeType;
3777 // For runtime type, let the VM decide.
3778 if (fromType != null)
3780 // both this and c (or their underlying system types) are runtime types
3781 return RuntimeTypeHandle.CanCastTo(fromType, this);
3783 #if !FULL_AOT_RUNTIME
3784 // Special case for TypeBuilder to be backward-compatible.
3785 if (RuntimeFeature.IsDynamicCodeSupported && c is System.Reflection.Emit.TypeBuilder)
3787 // If c is a subclass of this class, then c can be cast to this type.
3788 if (c.IsSubclassOf(this))
3789 return true;
3791 if (this.IsInterface)
3793 return c.ImplementInterface(this);
3795 else if (this.IsGenericParameter)
3797 Type[] constraints = GetGenericParameterConstraints();
3798 for (int i = 0; i < constraints.Length; i++)
3799 if (!constraints[i].IsAssignableFrom(c))
3800 return false;
3802 return true;
3805 #endif
3806 // For anything else we return false.
3807 return false;
3810 #if !FEATURE_CORECLR
3811 // Reflexive, symmetric, transitive.
3812 public override bool IsEquivalentTo(Type other)
3814 RuntimeType otherRtType = other as RuntimeType;
3815 if ((object)otherRtType == null)
3816 return false;
3818 if (otherRtType == this)
3819 return true;
3821 // It's not worth trying to perform further checks in managed
3822 // as they would lead to FCalls anyway.
3823 return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);
3825 #endif // FEATURE_CORECLR
3827 public override Type BaseType
3829 get
3831 return GetBaseType();
3835 private RuntimeType GetBaseType()
3837 if (IsInterface)
3838 return null;
3840 if (RuntimeTypeHandle.IsGenericVariable(this))
3842 Type[] constraints = GetGenericParameterConstraints();
3844 RuntimeType baseType = RuntimeType.ObjectType;
3846 for (int i = 0; i < constraints.Length; i++)
3848 RuntimeType constraint = (RuntimeType)constraints[i];
3850 if (constraint.IsInterface)
3851 continue;
3853 if (constraint.IsGenericParameter)
3855 GenericParameterAttributes special;
3856 special = constraint.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3858 if ((special & GenericParameterAttributes.ReferenceTypeConstraint) == 0 &&
3859 (special & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
3860 continue;
3863 baseType = constraint;
3866 if (baseType == RuntimeType.ObjectType)
3868 GenericParameterAttributes special;
3869 special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3870 if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
3871 baseType = RuntimeType.ValueType;
3874 return baseType;
3877 return RuntimeTypeHandle.GetBaseType(this);
3880 public override Type UnderlyingSystemType
3882 get
3884 return this;
3887 #endregion
3888 #if !MONO
3889 #region Name
3890 public override String FullName
3892 get
3894 return GetCachedName(TypeNameKind.FullName);
3898 public override String AssemblyQualifiedName
3900 get
3902 string fullname = FullName;
3904 // FullName is null if this type contains generic parameters but is not a generic type definition.
3905 if (fullname == null)
3906 return null;
3908 return Assembly.CreateQualifiedName(this.Assembly.FullName, fullname);
3912 public override String Namespace
3914 get
3916 string ns = Cache.GetNameSpace();
3918 if (ns == null || ns.Length == 0)
3919 return null;
3921 return ns;
3924 #endregion
3925 #endif
3926 #region Attributes
3927 [System.Security.SecuritySafeCritical] // auto-generated
3928 protected override TypeAttributes GetAttributeFlagsImpl()
3930 return RuntimeTypeHandle.GetAttributes(this);
3932 #if !MONO
3933 public override Guid GUID
3935 [System.Security.SecuritySafeCritical] // auto-generated
3936 get
3938 Guid result = new Guid ();
3939 GetGUID(ref result);
3940 return result;
3944 [System.Security.SecurityCritical] // auto-generated
3945 [ResourceExposure(ResourceScope.None)]
3946 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3947 private extern void GetGUID(ref Guid result);
3948 #endif
3949 [System.Security.SecuritySafeCritical] // auto-generated
3950 protected override bool IsContextfulImpl()
3952 return RuntimeTypeHandle.IsContextful(this);
3956 protected override bool IsMarshalByRefImpl()
3958 return GetTypeHandleInternal().IsMarshalByRef();
3962 protected override bool IsByRefImpl()
3964 return RuntimeTypeHandle.IsByRef(this);
3967 protected override bool IsPrimitiveImpl()
3969 return RuntimeTypeHandle.IsPrimitive(this);
3972 protected override bool IsPointerImpl()
3974 return RuntimeTypeHandle.IsPointer(this);
3977 [System.Security.SecuritySafeCritical] // auto-generated
3978 protected override bool IsCOMObjectImpl()
3980 return RuntimeTypeHandle.IsComObject(this, false);
3983 #if FEATURE_COMINTEROP
3984 [SecuritySafeCritical]
3985 internal override bool IsWindowsRuntimeObjectImpl()
3987 return IsWindowsRuntimeObjectType(this);
3990 [SecuritySafeCritical]
3991 internal override bool IsExportedToWindowsRuntimeImpl()
3993 return IsTypeExportedToWindowsRuntime(this);
3996 [MethodImplAttribute(MethodImplOptions.InternalCall)]
3997 [SecurityCritical]
3998 private static extern bool IsWindowsRuntimeObjectType(RuntimeType type);
4000 [MethodImplAttribute(MethodImplOptions.InternalCall)]
4001 [SecurityCritical]
4002 private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type);
4004 #endif // FEATURE_COMINTEROP
4006 #if !NETCORE
4007 [System.Security.SecuritySafeCritical] // auto-generated
4008 internal override bool HasProxyAttributeImpl()
4010 return RuntimeTypeHandle.HasProxyAttribute(this);
4012 #endif
4014 internal bool IsDelegate()
4016 return GetBaseType() == typeof(System.MulticastDelegate);
4019 protected override bool IsValueTypeImpl()
4021 // We need to return true for generic parameters with the ValueType constraint.
4022 // So we cannot use the faster RuntimeTypeHandle.IsValueType because it returns
4023 // false for all generic parameters.
4024 if (this == typeof(ValueType) || this == typeof(Enum))
4025 return false;
4027 return IsSubclassOf(typeof(ValueType));
4030 #if !FEATURE_CORECLR
4031 public override bool IsEnum
4035 return GetBaseType() == RuntimeType.EnumType;
4038 #endif
4040 protected override bool HasElementTypeImpl()
4042 return RuntimeTypeHandle.HasElementType(this);
4045 public override GenericParameterAttributes GenericParameterAttributes
4047 [System.Security.SecuritySafeCritical] // auto-generated
4050 if (!IsGenericParameter)
4051 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4052 Contract.EndContractBlock();
4054 #if MONO
4055 return GetGenericParameterAttributes ();
4056 #else
4057 GenericParameterAttributes attributes;
4059 RuntimeTypeHandle.GetMetadataImport(this).GetGenericParamProps(MetadataToken, out attributes);
4061 return attributes;
4062 #endif
4065 #if !MONO
4066 public override bool IsSecurityCritical
4068 get { return new RuntimeTypeHandle(this).IsSecurityCritical(); }
4070 public override bool IsSecuritySafeCritical
4072 get { return new RuntimeTypeHandle(this).IsSecuritySafeCritical(); }
4074 public override bool IsSecurityTransparent
4076 get { return new RuntimeTypeHandle(this).IsSecurityTransparent(); }
4078 #endif
4079 #endregion
4081 #region Arrays
4082 #if !NETCORE
4083 internal override bool IsSzArray
4085 get
4087 return RuntimeTypeHandle.IsSzArray(this);
4090 #endif
4092 protected override bool IsArrayImpl()
4094 return RuntimeTypeHandle.IsArray(this);
4097 [System.Security.SecuritySafeCritical] // auto-generated
4098 public override int GetArrayRank()
4100 if (!IsArrayImpl())
4101 throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
4103 return RuntimeTypeHandle.GetArrayRank(this);
4106 public override Type GetElementType()
4108 return RuntimeTypeHandle.GetElementType(this);
4110 #endregion
4112 #region Enums
4113 public override string[] GetEnumNames()
4115 if (!IsEnum)
4116 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4117 Contract.EndContractBlock();
4119 String[] ret = Enum.InternalGetNames(this);
4121 // Make a copy since we can't hand out the same array since users can modify them
4122 String[] retVal = new String[ret.Length];
4124 Array.Copy(ret, retVal, ret.Length);
4126 return retVal;
4129 [SecuritySafeCritical]
4130 public override Array GetEnumValues()
4132 if (!IsEnum)
4133 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4134 Contract.EndContractBlock();
4136 // Get all of the values
4137 ulong[] values = Enum.InternalGetValues(this);
4139 // Create a generic Array
4140 #if MONO
4141 Array ret = Array.CreateInstance(this, values.Length);
4142 #else
4143 Array ret = Array.UnsafeCreateInstance(this, values.Length);
4144 #endif
4146 for (int i = 0; i < values.Length; i++)
4148 Object val = Enum.ToObject(this, values[i]);
4149 ret.SetValue(val, i);
4152 return ret;
4155 public override Type GetEnumUnderlyingType()
4157 if (!IsEnum)
4158 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4159 Contract.EndContractBlock();
4161 return Enum.InternalGetUnderlyingType(this);
4164 public override bool IsEnumDefined(object value)
4166 if (value == null)
4167 throw new ArgumentNullException("value");
4168 Contract.EndContractBlock();
4170 // Check if both of them are of the same type
4171 RuntimeType valueType = (RuntimeType)value.GetType();
4173 // If the value is an Enum then we need to extract the underlying value from it
4174 if (valueType.IsEnum)
4176 if (!valueType.IsEquivalentTo(this))
4177 throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
4179 valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
4182 // If a string is passed in
4183 if (valueType == RuntimeType.StringType)
4185 // Get all of the Fields, calling GetHashEntry directly to avoid copying
4186 string[] names = Enum.InternalGetNames(this);
4187 if (Array.IndexOf(names, value) >= 0)
4188 return true;
4189 else
4190 return false;
4193 // If an enum or integer value is passed in
4194 if (Type.IsIntegerType(valueType))
4196 RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
4197 if (underlyingType != valueType)
4198 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
4200 ulong[] ulValues = Enum.InternalGetValues(this);
4201 ulong ulValue = Enum.ToUInt64(value);
4203 return (Array.BinarySearch(ulValues, ulValue) >= 0);
4205 #if !NETCORE
4206 else if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
4208 // if at this point the value type is not an integer type, then its type doesn't match the enum type
4209 // NetCF used to throw an argument exception in this case
4210 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), GetEnumUnderlyingType()));
4212 #endif
4213 else
4215 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
4219 public override string GetEnumName(object value)
4221 if (value == null)
4222 throw new ArgumentNullException("value");
4223 Contract.EndContractBlock();
4225 Type valueType = value.GetType();
4227 if (!(valueType.IsEnum || IsIntegerType(valueType)))
4228 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
4230 ulong[] ulValues = Enum.InternalGetValues(this);
4231 ulong ulValue = Enum.ToUInt64(value);
4232 int index = Array.BinarySearch(ulValues, ulValue);
4234 if (index >= 0)
4236 string[] names = Enum.InternalGetNames(this);
4237 return names[index];
4240 return null;
4242 #endregion
4244 #region Generics
4246 internal RuntimeType[] GetGenericArgumentsInternal()
4248 #if MONO
4249 return (RuntimeType[]) GetGenericArgumentsInternal (true);
4250 #else
4251 return GetRootElementType().GetTypeHandleInternal().GetInstantiationInternal();
4252 #endif
4255 public override Type[] GetGenericArguments()
4257 #if MONO
4258 Type[] types = GetGenericArgumentsInternal (false);
4259 #else
4260 Type[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiationPublic();
4261 #endif
4263 if (types == null)
4264 types = Array.Empty<Type> ();
4266 return types;
4269 [System.Security.SecuritySafeCritical] // auto-generated
4270 public override Type MakeGenericType(Type[] instantiation)
4272 if (instantiation == null)
4273 throw new ArgumentNullException("instantiation");
4274 Contract.EndContractBlock();
4276 RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length];
4278 if (!IsGenericTypeDefinition)
4279 throw new InvalidOperationException(
4280 Environment.GetResourceString("Arg_NotGenericTypeDefinition", this));
4282 if (GetGenericArguments().Length != instantiation.Length)
4283 throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), "instantiation");
4285 for (int i = 0; i < instantiation.Length; i ++)
4287 Type instantiationElem = instantiation[i];
4288 if (instantiationElem == null)
4289 throw new ArgumentNullException();
4291 RuntimeType rtInstantiationElem = instantiationElem as RuntimeType;
4293 if (rtInstantiationElem == null)
4295 #if MONO
4296 if (instantiationElem.IsSignatureType)
4297 return MakeGenericSignatureType (this, instantiation);
4298 #endif
4299 Type[] instantiationCopy = new Type[instantiation.Length];
4300 for (int iCopy = 0; iCopy < instantiation.Length; iCopy++)
4301 instantiationCopy[iCopy] = instantiation[iCopy];
4302 instantiation = instantiationCopy;
4303 #if NETCORE
4304 throw new NotImplementedException ();
4305 #else
4306 #pragma warning disable 162
4307 if (!RuntimeFeature.IsDynamicCodeSupported)
4308 throw new PlatformNotSupportedException();
4309 return System.Reflection.Emit.TypeBuilderInstantiation.MakeGenericType(this, instantiation);
4310 #pragma warning restore 162
4311 #endif
4314 instantiationRuntimeType[i] = rtInstantiationElem;
4317 RuntimeType[] genericParameters = GetGenericArgumentsInternal();
4319 SanityCheckGenericArguments(instantiationRuntimeType, genericParameters);
4321 Type ret = null;
4322 #if MONO
4323 ret = MakeGenericType (this, instantiationRuntimeType);
4324 if (ret == null)
4325 throw new TypeLoadException ();
4326 #else
4327 try
4329 ret = new RuntimeTypeHandle(this).Instantiate(instantiationRuntimeType);
4331 catch (TypeLoadException e)
4333 ValidateGenericArguments(this, instantiationRuntimeType, e);
4334 throw e;
4336 #endif
4337 return ret;
4340 public override bool IsGenericTypeDefinition
4342 get { return RuntimeTypeHandle.IsGenericTypeDefinition(this); }
4345 public override bool IsGenericParameter
4347 get { return RuntimeTypeHandle.IsGenericVariable(this); }
4350 public override int GenericParameterPosition
4352 get
4354 if (!IsGenericParameter)
4355 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4356 Contract.EndContractBlock();
4357 #if MONO
4358 return GetGenericParameterPosition ();
4359 #else
4360 return new RuntimeTypeHandle(this).GetGenericVariableIndex();
4361 #endif
4365 public override Type GetGenericTypeDefinition()
4367 if (!IsGenericType)
4368 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotGenericType"));
4369 Contract.EndContractBlock();
4371 return RuntimeTypeHandle.GetGenericTypeDefinition(this);
4374 public override bool IsGenericType
4376 get { return RuntimeTypeHandle.HasInstantiation(this); }
4379 public override bool IsConstructedGenericType
4381 get { return IsGenericType && !IsGenericTypeDefinition; }
4383 #if !MONO
4384 public override bool ContainsGenericParameters
4386 get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
4389 public override Type[] GetGenericParameterConstraints()
4391 if (!IsGenericParameter)
4392 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4393 Contract.EndContractBlock();
4395 Type[] constraints = new RuntimeTypeHandle(this).GetConstraints();
4397 if (constraints == null)
4398 constraints = EmptyArray<Type>.Value;
4400 return constraints;
4402 #endif
4403 #endregion
4404 #if !MONO
4405 #region Misc
4406 [System.Security.SecuritySafeCritical] // auto-generated
4407 public override Type MakePointerType() { return new RuntimeTypeHandle(this).MakePointer(); }
4408 public override Type MakeByRefType() { return new RuntimeTypeHandle(this).MakeByRef(); }
4409 public override Type MakeArrayType() { return new RuntimeTypeHandle(this).MakeSZArray(); }
4410 public override Type MakeArrayType(int rank)
4412 if (rank <= 0)
4413 throw new IndexOutOfRangeException();
4414 Contract.EndContractBlock();
4416 return new RuntimeTypeHandle(this).MakeArray(rank);
4418 public override StructLayoutAttribute StructLayoutAttribute
4420 [System.Security.SecuritySafeCritical] // overrides transparent public member
4421 get
4423 return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
4426 #endregion
4427 #endif
4428 #region Invoke Member
4429 private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
4430 private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
4431 private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
4432 private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
4433 private const BindingFlags BinderSetInvokeProperty = BindingFlags.InvokeMethod | BindingFlags.SetProperty;
4434 private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
4435 private const BindingFlags BinderSetInvokeField = BindingFlags.SetField | BindingFlags.InvokeMethod;
4436 private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
4437 private const BindingFlags ClassicBindingMask =
4438 BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
4439 BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
4440 private static RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
4441 #if !MONO
4442 [System.Security.SecurityCritical] // auto-generated
4443 [ResourceExposure(ResourceScope.None)]
4444 [MethodImplAttribute(MethodImplOptions.InternalCall)]
4445 static private extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
4447 [System.Security.SecurityCritical] // auto-generated
4448 [ResourceExposure(ResourceScope.None)]
4449 [MethodImplAttribute(MethodImplOptions.InternalCall)]
4450 static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange);
4452 [System.Security.SecuritySafeCritical] // auto-generated
4453 internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
4455 // this method is used by invocation in reflection to check whether a value can be assigned to type.
4456 if (IsInstanceOfType(value))
4458 // Since this cannot be a generic parameter, we use RuntimeTypeHandle.IsValueType here
4459 // because it is faster than RuntimeType.IsValueType
4460 Contract.Assert(!IsGenericParameter);
4462 Type type = null;
4464 #if FEATURE_REMOTING
4465 // For the remoting objects Object.GetType goes through proxy. Avoid the proxy call and just get
4466 // the type directly. It is necessary to support proxies that do not handle GetType.
4467 RealProxy realProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(value);
4469 if (realProxy != null)
4471 type = realProxy.GetProxiedType();
4473 else
4475 type = value.GetType();
4477 #else
4478 type = value.GetType();
4479 #endif
4481 if (!Object.ReferenceEquals(type, this) && RuntimeTypeHandle.IsValueType(this))
4483 // must be an equivalent type, re-box to the target type
4484 return AllocateValueType(this, value, true);
4486 else
4488 return value;
4492 // if this is a ByRef get the element type and check if it's compatible
4493 bool isByRef = IsByRef;
4494 if (isByRef)
4496 RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4497 if (elementType.IsInstanceOfType(value) || value == null)
4499 // need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
4500 return AllocateValueType(elementType, value, false);
4503 else if (value == null)
4504 return value;
4505 else if (this == s_typedRef)
4506 // everything works for a typedref
4507 return value;
4509 // check the strange ones courtesy of reflection:
4510 // - implicit cast between primitives
4511 // - enum treated as underlying type
4512 // - IntPtr and System.Reflection.Pointer to pointer types
4513 bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive;
4514 if (needsSpecialCast)
4516 RuntimeType valueType;
4517 Pointer pointer = value as Pointer;
4518 if (pointer != null)
4519 valueType = pointer.GetPointerType();
4520 else
4521 valueType = (RuntimeType)value.GetType();
4523 if (CanValueSpecialCast(valueType, this))
4525 if (pointer != null)
4526 return pointer.GetPointerValue();
4527 else
4528 return value;
4532 if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
4533 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4535 return TryChangeType(value, binder, culture, needsSpecialCast);
4538 // Factored out of CheckValue to reduce code complexity.
4539 [System.Security.SecurityCritical]
4540 private Object TryChangeType(Object value, Binder binder, CultureInfo culture, bool needsSpecialCast)
4542 if (binder != null && binder != Type.DefaultBinder)
4544 value = binder.ChangeType(value, this, culture);
4545 if (IsInstanceOfType(value))
4546 return value;
4547 // if this is a ByRef get the element type and check if it's compatible
4548 if (IsByRef)
4550 RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4551 if (elementType.IsInstanceOfType(value) || value == null)
4552 return AllocateValueType(elementType, value, false);
4554 else if (value == null)
4555 return value;
4556 if (needsSpecialCast)
4558 RuntimeType valueType;
4559 Pointer pointer = value as Pointer;
4560 if (pointer != null)
4561 valueType = pointer.GetPointerType();
4562 else
4563 valueType = (RuntimeType)value.GetType();
4565 if (CanValueSpecialCast(valueType, this))
4567 if (pointer != null)
4568 return pointer.GetPointerValue();
4569 else
4570 return value;
4575 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4577 #endif
4578 // GetDefaultMembers
4579 // This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
4580 public override MemberInfo[] GetDefaultMembers()
4582 // See if we have cached the default member name
4583 MemberInfo[] members = null;
4585 String defaultMemberName = GetDefaultMemberName();
4586 if (defaultMemberName != null)
4588 members = GetMember(defaultMemberName);
4591 if (members == null)
4592 members = Array.Empty<MemberInfo> ();
4594 return members;
4597 #if FEATURE_COMINTEROP
4598 [System.Security.SecuritySafeCritical] // auto-generated
4599 #endif
4600 [DebuggerStepThroughAttribute]
4601 [Diagnostics.DebuggerHidden]
4602 public override Object InvokeMember(
4603 String name, BindingFlags bindingFlags, Binder binder, Object target,
4604 Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
4606 if (IsGenericParameter)
4607 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
4608 Contract.EndContractBlock();
4610 #region Preconditions
4611 if ((bindingFlags & InvocationMask) == 0)
4612 // "Must specify binding flags describing the invoke operation required."
4613 throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),"bindingFlags");
4615 // Provide a default binding mask if none is provided
4616 if ((bindingFlags & MemberBindingMask) == 0)
4618 bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
4620 if ((bindingFlags & BindingFlags.CreateInstance) == 0)
4621 bindingFlags |= BindingFlags.Static;
4624 // There must not be more named parameters than provided arguments
4625 if (namedParams != null)
4627 if (providedArgs != null)
4629 if (namedParams.Length > providedArgs.Length)
4630 // "Named parameter array can not be bigger than argument array."
4631 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4633 else
4635 if (namedParams.Length != 0)
4636 // "Named parameter array can not be bigger than argument array."
4637 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4640 #endregion
4642 #region COM Interop
4643 #if FEATURE_COMINTEROP && FEATURE_USE_LCID
4644 if (target != null && target.GetType().IsCOMObject)
4646 #region Preconditions
4647 if ((bindingFlags & ClassicBindingMask) == 0)
4648 throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
4650 if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4651 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4653 if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4654 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4656 if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
4657 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4659 if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
4660 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4662 if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
4663 throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4664 #endregion
4666 #if FEATURE_REMOTING
4667 if(!RemotingServices.IsTransparentProxy(target))
4668 #endif
4670 #region Non-TransparentProxy case
4671 if (name == null)
4672 throw new ArgumentNullException("name");
4673 #if MONO
4674 throw new NotImplementedException ();
4675 #else
4676 bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
4678 // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
4679 int lcid = (culture == null ? 0x0409 : culture.LCID);
4681 return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
4682 #endif
4683 #endregion
4685 #if FEATURE_REMOTING
4686 else
4688 #if MONO
4689 throw new NotImplementedException ();
4690 #else
4691 #region TransparentProxy case
4692 return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
4693 #endregion
4694 #endif
4696 #endif // FEATURE_REMOTING
4698 #endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
4699 #endregion
4701 #region Check that any named paramters are not null
4702 if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
4703 // "Named parameter value must not be null."
4704 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),"namedParams");
4705 #endregion
4707 int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
4709 #region Get a Binder
4710 if (binder == null)
4711 binder = DefaultBinder;
4713 #if !MONO
4714 bool bDefaultBinder = (binder == DefaultBinder);
4715 #endif
4716 #endregion
4718 #region Delegate to Activator.CreateInstance
4719 if ((bindingFlags & BindingFlags.CreateInstance) != 0)
4721 if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
4722 // "Can not specify both CreateInstance and another access type."
4723 throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),"bindingFlags");
4725 return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
4727 #endregion
4729 // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
4730 if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
4731 bindingFlags |= BindingFlags.SetProperty;
4733 #region Name
4734 if (name == null)
4735 throw new ArgumentNullException("name");
4737 if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
4739 name = GetDefaultMemberName();
4741 if (name == null)
4743 // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
4744 name = "ToString";
4747 #endregion
4749 #region GetField or SetField
4750 bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
4751 bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
4753 if (IsGetField || IsSetField)
4755 #region Preconditions
4756 if (IsGetField)
4758 if (IsSetField)
4759 // "Can not specify both Get and Set on a field."
4760 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
4762 if ((bindingFlags & BindingFlags.SetProperty) != 0)
4763 // "Can not specify both GetField and SetProperty."
4764 throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags");
4766 else
4768 Contract.Assert(IsSetField);
4770 if (providedArgs == null)
4771 throw new ArgumentNullException("providedArgs");
4773 if ((bindingFlags & BindingFlags.GetProperty) != 0)
4774 // "Can not specify both SetField and GetProperty."
4775 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags");
4777 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4778 // "Can not specify Set on a Field and Invoke on a method."
4779 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"bindingFlags");
4781 #endregion
4783 #region Lookup Field
4784 FieldInfo selFld = null;
4785 FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
4787 Contract.Assert(flds != null);
4789 if (flds.Length == 1)
4791 selFld = flds[0];
4793 else if (flds.Length > 0)
4795 selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
4797 #endregion
4799 if (selFld != null)
4801 #region Invocation on a field
4802 if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
4804 #region Invocation of an array Field
4805 int idxCnt;
4807 if ((bindingFlags & BindingFlags.GetField) != 0)
4809 idxCnt = argCnt;
4811 else
4813 idxCnt = argCnt - 1;
4816 if (idxCnt > 0)
4818 // Verify that all of the index values are ints
4819 int[] idx = new int[idxCnt];
4820 for (int i=0;i<idxCnt;i++)
4822 try
4824 idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
4826 catch (InvalidCastException)
4828 throw new ArgumentException(Environment.GetResourceString("Arg_IndexMustBeInt"));
4832 // Set or get the value...
4833 Array a = (Array) selFld.GetValue(target);
4835 // Set or get the value in the array
4836 if ((bindingFlags & BindingFlags.GetField) != 0)
4838 return a.GetValue(idx);
4840 else
4842 a.SetValue(providedArgs[idxCnt],idx);
4843 return null;
4846 #endregion
4849 if (IsGetField)
4851 #region Get the field value
4852 if (argCnt != 0)
4853 throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
4855 return selFld.GetValue(target);
4856 #endregion
4858 else
4860 #region Set the field Value
4861 if (argCnt != 1)
4862 throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
4864 selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
4866 return null;
4867 #endregion
4869 #endregion
4872 if ((bindingFlags & BinderNonFieldGetSet) == 0)
4873 throw new MissingFieldException(FullName, name);
4875 #endregion
4877 #region Caching Logic
4879 bool useCache = false;
4881 // Note that when we add something to the cache, we are careful to ensure
4882 // that the actual providedArgs matches the parameters of the method. Otherwise,
4883 // some default argument processing has occurred. We don't want anyone
4884 // else with the same (insufficient) number of actual arguments to get a
4885 // cache hit because then they would bypass the default argument processing
4886 // and the invocation would fail.
4887 if (bDefaultBinder && namedParams == null && argCnt < 6)
4888 useCache = true;
4890 if (useCache)
4892 MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
4894 if (invokeMethod != null)
4895 return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
4898 #endregion
4900 #region Property PreConditions
4901 // @Legacy - This is RTM behavior
4902 bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
4903 bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
4905 if (isGetProperty || isSetProperty)
4907 #region Preconditions
4908 if (isGetProperty)
4910 Contract.Assert(!IsSetField);
4912 if (isSetProperty)
4913 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4915 else
4917 Contract.Assert(isSetProperty);
4919 Contract.Assert(!IsGetField);
4921 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4922 throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4924 #endregion
4926 #endregion
4928 MethodInfo[] finalists = null;
4929 MethodInfo finalist = null;
4931 #region BindingFlags.InvokeMethod
4932 if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4934 #region Lookup Methods
4935 MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
4936 List<MethodInfo> results = null;
4938 for(int i = 0; i < semiFinalists.Length; i ++)
4940 MethodInfo semiFinalist = semiFinalists[i];
4941 Contract.Assert(semiFinalist != null);
4943 if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4944 continue;
4946 if (finalist == null)
4948 finalist = semiFinalist;
4950 else
4952 if (results == null)
4954 results = new List<MethodInfo>(semiFinalists.Length);
4955 results.Add(finalist);
4958 results.Add(semiFinalist);
4962 if (results != null)
4964 Contract.Assert(results.Count > 1);
4965 finalists = new MethodInfo[results.Count];
4966 results.CopyTo(finalists);
4968 #endregion
4970 #endregion
4972 Contract.Assert(finalists == null || finalist != null);
4974 #region BindingFlags.GetProperty or BindingFlags.SetProperty
4975 if (finalist == null && isGetProperty || isSetProperty)
4977 #region Lookup Property
4978 PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
4979 List<MethodInfo> results = null;
4981 for(int i = 0; i < semiFinalists.Length; i ++)
4983 MethodInfo semiFinalist = null;
4985 if (isSetProperty)
4987 semiFinalist = semiFinalists[i].GetSetMethod(true);
4989 else
4991 semiFinalist = semiFinalists[i].GetGetMethod(true);
4994 if (semiFinalist == null)
4995 continue;
4997 if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4998 continue;
5000 if (finalist == null)
5002 finalist = semiFinalist;
5004 else
5006 if (results == null)
5008 results = new List<MethodInfo>(semiFinalists.Length);
5009 results.Add(finalist);
5012 results.Add(semiFinalist);
5016 if (results != null)
5018 Contract.Assert(results.Count > 1);
5019 finalists = new MethodInfo[results.Count];
5020 results.CopyTo(finalists);
5022 #endregion
5024 #endregion
5026 if (finalist != null)
5028 #region Invoke
5029 if (finalists == null &&
5030 argCnt == 0 &&
5031 finalist.GetParametersNoCopy().Length == 0 &&
5032 (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
5034 //if (useCache && argCnt == props[0].GetParameters().Length)
5035 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
5037 return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
5040 if (finalists == null)
5041 finalists = new MethodInfo[] { finalist };
5043 if (providedArgs == null)
5044 providedArgs = Array.Empty<Object>();
5046 Object state = null;
5049 MethodBase invokeMethod = null;
5051 try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
5052 catch(MissingMethodException) { }
5054 if (invokeMethod == null)
5055 throw new MissingMethodException(FullName, name);
5057 //if (useCache && argCnt == invokeMethod.GetParameters().Length)
5058 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
5060 Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
5062 if (state != null)
5063 binder.ReorderArgumentArray(ref providedArgs, state);
5065 return result;
5066 #endregion
5069 throw new MissingMethodException(FullName, name);
5071 #endregion
5073 #region Object Overrides
5074 [Pure]
5075 public override bool Equals(object obj)
5077 // ComObjects are identified by the instance of the Type object and not the TypeHandle.
5078 return obj == (object)this;
5081 #if !MONO || NETCORE
5082 public override int GetHashCode()
5084 return RuntimeHelpers.GetHashCode(this);
5086 #endif
5088 #if !FEATURE_CORECLR
5089 public static bool operator ==(RuntimeType left, RuntimeType right)
5091 return object.ReferenceEquals(left, right);
5094 public static bool operator !=(RuntimeType left, RuntimeType right)
5096 return !object.ReferenceEquals(left, right);
5098 #endif // !FEATURE_CORECLR
5099 #if !MONO
5100 public override String ToString()
5102 return GetCachedName(TypeNameKind.ToString);
5104 #endif
5105 #endregion
5107 #region ICloneable
5108 public Object Clone()
5110 return this;
5112 #endregion
5114 #region ISerializable
5115 [System.Security.SecurityCritical] // auto-generated
5116 public void GetObjectData(SerializationInfo info, StreamingContext context)
5118 if (info==null)
5119 throw new ArgumentNullException("info");
5120 Contract.EndContractBlock();
5122 #if NETCORE
5123 throw new NotImplementedException ();
5124 #else
5125 UnitySerializationHolder.GetUnitySerializationInfo(info, this);
5126 #endif
5128 #endregion
5130 #region ICustomAttributeProvider
5131 [System.Security.SecuritySafeCritical] // auto-generated
5132 public override Object[] GetCustomAttributes(bool inherit)
5134 #if NETCORE
5135 return CustomAttribute.GetCustomAttributes(this, inherit);
5136 #else
5137 return CustomAttribute.GetCustomAttributes(this, RuntimeType.ObjectType, inherit);
5138 #endif
5141 [System.Security.SecuritySafeCritical] // auto-generated
5142 public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
5144 if ((object)attributeType == null)
5145 throw new ArgumentNullException("attributeType");
5146 Contract.EndContractBlock();
5148 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5150 if (attributeRuntimeType == null)
5151 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5153 return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
5156 [System.Security.SecuritySafeCritical] // auto-generated
5157 public override bool IsDefined(Type attributeType, bool inherit)
5159 if ((object)attributeType == null)
5160 throw new ArgumentNullException("attributeType");
5161 Contract.EndContractBlock();
5163 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5165 if (attributeRuntimeType == null)
5166 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5168 return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
5171 public override IList<CustomAttributeData> GetCustomAttributesData()
5173 return CustomAttributeData.GetCustomAttributesInternal(this);
5175 #endregion
5177 #region MemberInfo Overrides
5178 #if !MONO
5179 public override String Name
5181 get
5183 return GetCachedName(TypeNameKind.Name);
5187 #endif
5188 // This is used by the ToString() overrides of all reflection types. The legacy behavior has the following problems:
5189 // 1. Use only Name for nested types, which can be confused with global types and generic parameters of the same name.
5190 // 2. Use only Name for generic parameters, which can be confused with nested types and global types of the same name.
5191 // 3. Remove the namespace ("System") for all primitive types, which is not language neutral.
5192 // 4. MethodBase.ToString() use "ByRef" for byref parameters which is different than Type.ToString().
5193 // 5. ConstructorInfo.ToString() outputs "Void" as the return type. Why Void?
5194 // Since it could be a breaking changes to fix these legacy behaviors, we only use the better and more unambiguous format
5195 // in serialization (MemberInfoSerializationHolder).
5196 internal override string FormatTypeName(bool serialization)
5198 if (serialization)
5200 return GetCachedName(TypeNameKind.SerializationName);
5202 else
5204 Type elementType = GetRootElementType();
5206 // Legacy: this doesn't make sense, why use only Name for nested types but otherwise
5207 // ToString() which contains namespace.
5208 if (elementType.IsNested)
5209 return Name;
5211 string typeName = ToString();
5213 // Legacy: why removing "System"? Is it just because C# has keywords for these types?
5214 // If so why don't we change it to lower case to match the C# keyword casing?
5215 if (elementType.IsPrimitive ||
5216 elementType == typeof(void) ||
5217 elementType == typeof(TypedReference))
5219 typeName = typeName.Substring(@"System.".Length);
5222 return typeName;
5226 #if !MONO
5228 private string GetCachedName(TypeNameKind kind)
5230 return Cache.GetName(kind);
5232 #endif
5233 public override MemberTypes MemberType
5235 get
5237 if (this.IsPublic || this.IsNotPublic)
5238 return MemberTypes.TypeInfo;
5239 else
5240 return MemberTypes.NestedType;
5243 #if !MONO
5244 public override Type DeclaringType
5246 get
5248 return Cache.GetEnclosingType();
5251 #endif
5252 public override Type ReflectedType
5254 get
5256 return DeclaringType;
5260 public override int MetadataToken
5262 [System.Security.SecuritySafeCritical] // auto-generated
5263 get
5265 return RuntimeTypeHandle.GetToken(this);
5268 #endregion
5270 #region Legacy Internal
5271 private void CreateInstanceCheckThis()
5273 if (this is ReflectionOnlyType)
5274 throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
5276 if (ContainsGenericParameters)
5277 throw new ArgumentException(
5278 Environment.GetResourceString("Acc_CreateGenericEx", this));
5279 Contract.EndContractBlock();
5281 Type elementType = this.GetRootElementType();
5283 if (Object.ReferenceEquals(elementType, typeof(ArgIterator)))
5284 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateArgIterator"));
5286 if (Object.ReferenceEquals(elementType, typeof(void)))
5287 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateVoid"));
5290 [System.Security.SecurityCritical] // auto-generated
5291 internal Object CreateInstanceImpl(
5292 BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture
5293 #if !NETCORE
5294 ,Object[] activationAttributes,
5295 ref StackCrawlMark stackMark
5296 #endif
5299 CreateInstanceCheckThis();
5301 Object server = null;
5307 // Store the activation attributes in thread local storage.
5308 // These attributes are later picked up by specialized
5309 // activation services like remote activation services to
5310 // influence the activation.
5311 #if FEATURE_REMOTING
5312 if(null != activationAttributes)
5314 ActivationServices.PushActivationAttributes(this, activationAttributes);
5316 #endif
5318 if (args == null)
5319 args = Array.Empty<Object> ();
5321 int argCnt = args.Length;
5323 // Without a binder we need to do use the default binder...
5324 if (binder == null)
5325 binder = DefaultBinder;
5327 // deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
5328 // so a call to GetMemberCons would fail
5329 bool publicOnly = (bindingAttr & BindingFlags.NonPublic) == 0;
5330 bool wrapExceptions = (bindingAttr & BindingFlags.DoNotWrapExceptions) == 0;
5331 if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
5332 && (IsGenericCOMObjectImpl() || IsValueType))
5334 server = CreateInstanceDefaultCtor(publicOnly, false, true, wrapExceptions
5335 #if !NETCORE
5336 , ref stackMark
5337 #endif
5340 else
5342 ConstructorInfo[] candidates = GetConstructors(bindingAttr);
5343 List<MethodBase> matches = new List<MethodBase>(candidates.Length);
5345 // We cannot use Type.GetTypeArray here because some of the args might be null
5346 Type[] argsType = new Type[argCnt];
5347 for (int i = 0; i < argCnt; i++)
5349 if (args[i] != null)
5351 argsType[i] = args[i].GetType();
5355 for(int i = 0; i < candidates.Length; i ++)
5357 if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
5358 matches.Add(candidates[i]);
5361 MethodBase[] cons = new MethodBase[matches.Count];
5362 matches.CopyTo(cons);
5363 if (cons != null && cons.Length == 0)
5364 cons = null;
5366 if (cons == null)
5368 // Null out activation attributes before throwing exception
5369 #if FEATURE_REMOTING
5370 if(null != activationAttributes)
5372 ActivationServices.PopActivationAttributes(this);
5373 activationAttributes = null;
5375 #endif
5376 throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5379 MethodBase invokeMethod;
5380 Object state = null;
5384 invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
5386 catch (MissingMethodException) { invokeMethod = null; }
5388 if (invokeMethod == null)
5390 #if FEATURE_REMOTING
5391 // Null out activation attributes before throwing exception
5392 if(null != activationAttributes)
5394 ActivationServices.PopActivationAttributes(this);
5395 activationAttributes = null;
5397 #endif
5398 throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5401 #if MONO_FEATURE_CAS
5402 // If we're creating a delegate, we're about to call a
5403 // constructor taking an integer to represent a target
5404 // method. Since this is very difficult (and expensive)
5405 // to verify, we're just going to demand UnmanagedCode
5406 // permission before allowing this. Partially trusted
5407 // clients can instead use Delegate.CreateDelegate,
5408 // which allows specification of the target method via
5409 // name or MethodInfo.
5410 //if (isDelegate)
5411 if (RuntimeType.DelegateType.IsAssignableFrom(invokeMethod.DeclaringType))
5413 #if FEATURE_CORECLR
5414 // In CoreCLR, CAS is not exposed externally. So what we really are looking
5415 // for is to see if the external caller of this API is transparent or not.
5416 // We get that information from the fact that a Demand will succeed only if
5417 // the external caller is not transparent.
5420 #pragma warning disable 618
5421 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5422 #pragma warning restore 618
5424 catch
5426 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_DelegateCreationFromPT")));
5428 #else // FEATURE_CORECLR
5429 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5430 #endif // FEATURE_CORECLR
5432 #endif // MONO_FEATURE_CAS
5433 if (invokeMethod.GetParametersNoCopy().Length == 0)
5435 if (args.Length != 0)
5438 Contract.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
5439 CallingConventions.VarArgs);
5440 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
5441 Environment.GetResourceString("NotSupported_CallToVarArg")));
5444 #if MONO && FEATURE_REMOTING
5445 if (activationAttributes != null && activationAttributes.Length != 0) {
5446 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5447 } else {
5448 #endif
5449 // fast path??
5450 server = Activator.CreateInstance(this, nonPublic: true, wrapExceptions: wrapExceptions);
5451 #if MONO && FEATURE_REMOTING
5453 #endif
5455 else
5457 #if MONO && FEATURE_REMOTING
5459 if (activationAttributes != null && activationAttributes.Length != 0) {
5460 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5461 } else {
5462 #endif
5463 server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
5464 #if MONO && FEATURE_REMOTING
5466 #endif
5468 if (state != null)
5469 binder.ReorderArgumentArray(ref args, state);
5473 finally
5475 #if FEATURE_REMOTING
5476 // Reset the TLS to null
5477 if(null != activationAttributes)
5479 ActivationServices.PopActivationAttributes(this);
5480 activationAttributes = null;
5482 #endif
5485 catch (Exception)
5487 throw;
5490 //Console.WriteLine(server);
5491 return server;
5494 #if MONO
5495 #if FEATURE_REMOTING
5497 // .NET seems to do this deep in method invocation which looks odd as it
5498 // needs extra push/pop as PushActivationAttributes/PopActivationAttributes.
5499 // We let them do nothing and have all logic here without complicated checks
5500 // inside fast path invoke.
5502 object ActivationCreateInstance (MethodBase invokeMethod, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
5504 var server = ActivationServices.CreateProxyFromAttributes (this, activationAttributes);
5505 if (server != null)
5506 invokeMethod.Invoke (server, bindingAttr, binder, args, culture);
5508 return server;
5510 #endif
5511 #else
5512 // the cache entry
5513 class ActivatorCacheEntry
5515 // the type to cache
5516 internal readonly RuntimeType m_type;
5517 // the delegate containing the call to the ctor, will be replaced by an IntPtr to feed a calli with
5518 internal volatile CtorDelegate m_ctor;
5519 internal readonly RuntimeMethodHandleInternal m_hCtorMethodHandle;
5520 internal readonly MethodAttributes m_ctorAttributes;
5521 // Is a security check needed before this constructor is invoked?
5522 internal readonly bool m_bNeedSecurityCheck;
5523 // Lazy initialization was performed
5524 internal volatile bool m_bFullyInitialized;
5526 [System.Security.SecurityCritical]
5527 internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh, bool bNeedSecurityCheck)
5529 m_type = t;
5530 m_bNeedSecurityCheck = bNeedSecurityCheck;
5531 m_hCtorMethodHandle = rmh;
5532 if (!m_hCtorMethodHandle.IsNullHandle())
5533 m_ctorAttributes = RuntimeMethodHandle.GetAttributes(m_hCtorMethodHandle);
5537 //ActivatorCache
5538 class ActivatorCache
5540 const int CACHE_SIZE = 16;
5541 volatile int hash_counter; //Counter for wrap around
5542 readonly ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE];
5544 volatile ConstructorInfo delegateCtorInfo;
5545 volatile PermissionSet delegateCreatePermissions;
5547 private void InitializeDelegateCreator() {
5548 // No synchronization needed here. In the worst case we create extra garbage
5549 PermissionSet ps = new PermissionSet(PermissionState.None);
5550 ps.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
5551 #pragma warning disable 618
5552 ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
5553 #pragma warning restore 618
5554 delegateCreatePermissions = ps;
5556 ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
5557 delegateCtorInfo = ctorInfo; // this assignment should be last
5560 [System.Security.SecuritySafeCritical] // auto-generated
5561 private void InitializeCacheEntry(ActivatorCacheEntry ace)
5563 if (!ace.m_type.IsValueType)
5565 Contract.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
5567 if (delegateCtorInfo == null)
5568 InitializeDelegateCreator();
5569 delegateCreatePermissions.Assert();
5571 // No synchronization needed here. In the worst case we create extra garbage
5572 CtorDelegate ctor = (CtorDelegate)delegateCtorInfo.Invoke(new Object[] { null, RuntimeMethodHandle.GetFunctionPointer(ace.m_hCtorMethodHandle) });
5573 ace.m_ctor = ctor;
5575 ace.m_bFullyInitialized = true;
5578 internal ActivatorCacheEntry GetEntry(RuntimeType t)
5580 int index = hash_counter;
5581 for(int i = 0; i < CACHE_SIZE; i++)
5583 ActivatorCacheEntry ace = Volatile.Read(ref cache[index]);
5584 if (ace != null && ace.m_type == t) //check for type match..
5586 if (!ace.m_bFullyInitialized)
5587 InitializeCacheEntry(ace);
5588 return ace;
5590 index = (index+1)&(ActivatorCache.CACHE_SIZE-1);
5592 return null;
5595 internal void SetEntry(ActivatorCacheEntry ace)
5597 // fill the the array backwards to hit the most recently filled entries first in GetEntry
5598 int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1);
5599 hash_counter = index;
5600 Volatile.Write(ref cache[index], ace);
5604 private static volatile ActivatorCache s_ActivatorCache;
5606 // the slow path of CreateInstanceDefaultCtor
5607 [System.Security.SecuritySafeCritical] // auto-generated
5608 internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache
5609 #if !NETCORE
5610 , ref StackCrawlMark stackMark
5611 #endif
5614 RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
5615 bool bNeedSecurityCheck = true;
5616 bool bCanBeCached = false;
5617 bool bSecurityCheckOff = false;
5619 if (!skipCheckThis)
5620 CreateInstanceCheckThis();
5622 if (!fillCache)
5623 bSecurityCheckOff = true;
5625 #if FEATURE_APPX
5626 INVOCATION_FLAGS invocationFlags = InvocationFlags;
5627 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
5629 RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
5630 if (caller != null && !caller.IsSafeForReflection())
5631 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", this.FullName));
5633 // Allow it because the caller is framework code, but don't cache the result
5634 // because we need to do the stack walk every time this type is instantiated.
5635 bSecurityCheckOff = false;
5636 bCanBeCached = false;
5638 #endif
5640 Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck);
5642 if (bCanBeCached && fillCache)
5644 ActivatorCache activatorCache = s_ActivatorCache;
5645 if (activatorCache == null)
5647 // No synchronization needed here. In the worst case we create extra garbage
5648 activatorCache = new ActivatorCache();
5649 s_ActivatorCache = activatorCache;
5652 // cache the ctor
5653 ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
5654 activatorCache.SetEntry(ace);
5657 return instance;
5659 #endif
5660 // Helper to invoke the default (parameterless) ctor.
5661 // fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
5662 [System.Security.SecuritySafeCritical] // auto-generated
5663 [DebuggerStepThroughAttribute]
5664 [Diagnostics.DebuggerHidden]
5665 internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, bool wrapExceptions
5666 #if !NETCORE
5667 , ref StackCrawlMark stackMark
5668 #endif
5671 #if NETCORE
5672 if (IsByRefLike)
5673 throw new NotSupportedException (SR.NotSupported_ByRefLike);
5674 #endif
5676 if (GetType() == typeof(ReflectionOnlyType))
5677 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5678 #if !MONO
5679 ActivatorCache activatorCache = s_ActivatorCache;
5680 if (activatorCache != null)
5682 ActivatorCacheEntry ace = activatorCache.GetEntry(this);
5683 if (ace != null)
5685 if (publicOnly)
5687 if (ace.m_ctor != null &&
5688 (ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5690 throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
5694 // Allocate empty object
5695 Object instance = RuntimeTypeHandle.Allocate(this);
5697 // if m_ctor is null, this type doesn't have a default ctor
5698 Contract.Assert(ace.m_ctor != null || this.IsValueType);
5700 if (ace.m_ctor != null)
5702 // Perform security checks if needed
5703 if (ace.m_bNeedSecurityCheck)
5704 RuntimeMethodHandle.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, this, (uint)INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
5706 // Call ctor (value types wont have any)
5709 ace.m_ctor(instance);
5711 catch (Exception e)
5713 throw new TargetInvocationException(e);
5716 return instance;
5720 return CreateInstanceSlow(publicOnly, wrapExceptions, skipCheckThis, fillCache, ref stackMark);
5721 #else
5722 return CreateInstanceSlow(publicOnly, wrapExceptions, skipCheckThis, fillCache);
5723 #endif
5726 #if !MONO
5727 internal void InvalidateCachedNestedType()
5729 Cache.InvalidateCachedNestedType();
5732 [System.Security.SecuritySafeCritical] // auto-generated
5733 internal bool IsGenericCOMObjectImpl()
5735 return RuntimeTypeHandle.IsComObject(this, true);
5737 #endif
5738 #endregion
5739 #if !MONO
5740 #region Legacy Static Internal
5741 [System.Security.SecurityCritical]
5742 [ResourceExposure(ResourceScope.None)]
5743 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5744 private static extern Object _CreateEnum(RuntimeType enumType, long value);
5745 [System.Security.SecuritySafeCritical] // auto-generated
5746 internal static Object CreateEnum(RuntimeType enumType, long value)
5748 return _CreateEnum(enumType, value);
5751 #if FEATURE_COMINTEROP
5752 [System.Security.SecurityCritical] // auto-generated
5753 [ResourceExposure(ResourceScope.None)]
5754 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5755 private extern Object InvokeDispMethod(
5756 String name, BindingFlags invokeAttr, Object target, Object[] args,
5757 bool[] byrefModifiers, int culture, String[] namedParameters);
5759 #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5760 [System.Security.SecurityCritical] // auto-generated
5761 [ResourceExposure(ResourceScope.None)]
5762 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5763 internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
5765 [System.Security.SecurityCritical] // auto-generated
5766 [ResourceExposure(ResourceScope.None)]
5767 [MethodImplAttribute(MethodImplOptions.InternalCall)]
5768 internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError);
5769 #else // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5770 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
5772 throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5775 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
5777 throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5779 #endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5780 #endif
5782 #endregion
5783 #endif
5784 #region COM
5785 #if FEATURE_COMINTEROP && FEATURE_REMOTING && !MONO
5786 [System.Security.SecuritySafeCritical] // auto-generated
5787 private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
5789 ParameterModifier[] aParamMod = null;
5790 Object ret = null;
5792 // Allocate a new message
5793 Message reqMsg = new Message();
5794 reqMsg.InitFields(msgData);
5796 // Retrieve the required information from the message object.
5797 MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase();
5798 Object[] aArgs = reqMsg.Args;
5799 int cArgs = aArgs.Length;
5801 // Retrieve information from the method we are invoking on.
5802 ParameterInfo[] aParams = meth.GetParametersNoCopy();
5804 // If we have arguments, then set the byref flags to true for byref arguments.
5805 // We also wrap the arguments that require wrapping.
5806 if (cArgs > 0)
5808 ParameterModifier paramMod = new ParameterModifier(cArgs);
5809 for (int i = 0; i < cArgs; i++)
5811 if (aParams[i].ParameterType.IsByRef)
5812 paramMod[i] = true;
5815 aParamMod = new ParameterModifier[1];
5816 aParamMod[0] = paramMod;
5818 if (aWrapperTypes != null)
5819 WrapArgsForInvokeCall(aArgs, aWrapperTypes);
5822 // If the method has a void return type, then set the IgnoreReturn binding flag.
5823 if (Object.ReferenceEquals(meth.ReturnType, typeof(void)))
5824 flags |= BindingFlags.IgnoreReturn;
5828 // Invoke the method using InvokeMember().
5829 ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
5831 catch (TargetInvocationException e)
5833 // For target invocation exceptions, we need to unwrap the inner exception and
5834 // re-throw it.
5835 throw e.InnerException;
5838 // Convert each byref argument that is not of the proper type to
5839 // the parameter type using the OleAutBinder.
5840 for (int i = 0; i < cArgs; i++)
5842 if (aParamMod[0][i] && aArgs[i] != null)
5844 // The parameter is byref.
5845 Type paramType = aParams[i].ParameterType.GetElementType();
5846 if (!Object.ReferenceEquals(paramType, aArgs[i].GetType()))
5847 aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
5851 // If the return type is not of the proper type, then convert it
5852 // to the proper type using the OleAutBinder.
5853 if (ret != null)
5855 Type retType = meth.ReturnType;
5856 if (!Object.ReferenceEquals(retType, ret.GetType()))
5857 ret = ForwardCallBinder.ChangeType(ret, retType, null);
5860 // Propagate the out parameters
5861 RealProxy.PropagateOutParameters(reqMsg, aArgs, ret);
5863 // Return the value returned by the InvokeMember call.
5864 return ret;
5867 [SecuritySafeCritical]
5868 private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes)
5870 int cArgs = aArgs.Length;
5871 for (int i = 0; i < cArgs; i++)
5873 if (aWrapperTypes[i] == 0)
5874 continue;
5876 if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
5878 Type wrapperType = null;
5879 bool isString = false;
5881 // Determine the type of wrapper to use.
5882 switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray)
5884 case DispatchWrapperType.Unknown:
5885 wrapperType = typeof(UnknownWrapper);
5886 break;
5887 case DispatchWrapperType.Dispatch:
5888 wrapperType = typeof(DispatchWrapper);
5889 break;
5890 case DispatchWrapperType.Error:
5891 wrapperType = typeof(ErrorWrapper);
5892 break;
5893 case DispatchWrapperType.Currency:
5894 wrapperType = typeof(CurrencyWrapper);
5895 break;
5896 case DispatchWrapperType.BStr:
5897 wrapperType = typeof(BStrWrapper);
5898 isString = true;
5899 break;
5900 default:
5901 Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
5902 break;
5905 // Allocate the new array of wrappers.
5906 Array oldArray = (Array)aArgs[i];
5907 int numElems = oldArray.Length;
5908 Object[] newArray = (Object[])Array.UnsafeCreateInstance(wrapperType, numElems);
5910 // Retrieve the ConstructorInfo for the wrapper type.
5911 ConstructorInfo wrapperCons;
5912 if(isString)
5914 wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
5916 else
5918 wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)});
5921 // Wrap each of the elements of the array.
5922 for (int currElem = 0; currElem < numElems; currElem++)
5924 if(isString)
5926 newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
5928 else
5930 newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
5934 // Update the argument.
5935 aArgs[i] = newArray;
5937 else
5939 // Determine the wrapper to use and then wrap the argument.
5940 switch ((DispatchWrapperType)aWrapperTypes[i])
5942 case DispatchWrapperType.Unknown:
5943 aArgs[i] = new UnknownWrapper(aArgs[i]);
5944 break;
5945 case DispatchWrapperType.Dispatch:
5946 aArgs[i] = new DispatchWrapper(aArgs[i]);
5947 break;
5948 case DispatchWrapperType.Error:
5949 aArgs[i] = new ErrorWrapper(aArgs[i]);
5950 break;
5951 case DispatchWrapperType.Currency:
5952 aArgs[i] = new CurrencyWrapper(aArgs[i]);
5953 break;
5954 case DispatchWrapperType.BStr:
5955 aArgs[i] = new BStrWrapper((String)aArgs[i]);
5956 break;
5957 default:
5958 Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified.");
5959 break;
5965 private OleAutBinder ForwardCallBinder
5967 get
5969 // Synchronization is not required.
5970 if (s_ForwardCallBinder == null)
5971 s_ForwardCallBinder = new OleAutBinder();
5973 return s_ForwardCallBinder;
5977 [Flags]
5978 private enum DispatchWrapperType : int
5980 // This enum must stay in sync with the DispatchWrapperType enum defined in MLInfo.h
5981 Unknown = 0x00000001,
5982 Dispatch = 0x00000002,
5983 Record = 0x00000004,
5984 Error = 0x00000008,
5985 Currency = 0x00000010,
5986 BStr = 0x00000020,
5987 SafeArray = 0x00010000
5990 private static volatile OleAutBinder s_ForwardCallBinder;
5991 #endif // FEATURE_COMINTEROP && FEATURE_REMOTING
5992 #endregion
5995 // this is the introspection only type. This type overrides all the functions with runtime semantics
5996 // and throws an exception.
5997 // The idea behind this type is that it relieves RuntimeType from doing honerous checks about ReflectionOnly
5998 // context.
5999 // This type should not derive from RuntimeType but it's doing so for convinience.
6000 // That should not present a security threat though it is risky as a direct call to one of the base method
6001 // method (RuntimeType) and an instance of this type will work around the reason to have this type in the
6002 // first place. However given RuntimeType is not public all its methods are protected and require full trust
6003 // to be accessed
6004 [Serializable]
6005 internal class ReflectionOnlyType : RuntimeType {
6007 private ReflectionOnlyType() {}
6009 // always throw
6010 public override RuntimeTypeHandle TypeHandle
6012 get
6014 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
6019 #if !MONO
6020 #region Library
6021 internal unsafe struct Utf8String
6023 [System.Security.SecurityCritical] // auto-generated
6024 [ResourceExposure(ResourceScope.None)]
6025 [MethodImplAttribute(MethodImplOptions.InternalCall)]
6026 private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz);
6028 [System.Security.SecurityCritical] // auto-generated
6029 [ResourceExposure(ResourceScope.None)]
6030 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
6031 [SuppressUnmanagedCodeSecurity]
6032 private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);
6034 [System.Security.SecurityCritical] // auto-generated
6035 [ResourceExposure(ResourceScope.None)]
6036 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
6037 [SuppressUnmanagedCodeSecurity]
6038 private static extern unsafe uint HashCaseInsensitive(void* sz, int cSz);
6040 [System.Security.SecurityCritical] // auto-generated
6041 private static int GetUtf8StringByteLength(void* pUtf8String)
6043 int len = 0;
6045 unsafe
6047 byte* pItr = (byte*)pUtf8String;
6049 while (*pItr != 0)
6051 len++;
6052 pItr++;
6056 return len;
6059 [SecurityCritical]
6060 private void* m_pStringHeap; // This is the raw UTF8 string.
6061 private int m_StringHeapByteLength;
6063 [System.Security.SecurityCritical] // auto-generated
6064 internal Utf8String(void* pStringHeap)
6066 m_pStringHeap = pStringHeap;
6067 if (pStringHeap != null)
6069 m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap);
6071 else
6073 m_StringHeapByteLength = 0;
6077 [System.Security.SecurityCritical] // auto-generated
6078 internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
6080 m_pStringHeap = pUtf8String;
6081 m_StringHeapByteLength = cUtf8String;
6084 [System.Security.SecuritySafeCritical] // auto-generated
6085 internal unsafe bool Equals(Utf8String s)
6087 if (m_pStringHeap == null)
6089 return s.m_StringHeapByteLength == 0;
6091 if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6093 return Utf8String.EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6095 return false;
6098 [System.Security.SecuritySafeCritical] // auto-generated
6099 internal unsafe bool EqualsCaseInsensitive(Utf8String s)
6101 if (m_pStringHeap == null)
6103 return s.m_StringHeapByteLength == 0;
6105 if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6107 return Utf8String.EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6109 return false;
6112 [System.Security.SecuritySafeCritical] // auto-generated
6113 internal unsafe uint HashCaseInsensitive()
6115 return Utf8String.HashCaseInsensitive(m_pStringHeap, m_StringHeapByteLength);
6118 [System.Security.SecuritySafeCritical] // auto-generated
6119 public override string ToString()
6121 unsafe
6123 byte* buf = stackalloc byte[m_StringHeapByteLength];
6124 byte* pItr = (byte*)m_pStringHeap;
6126 for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++)
6128 buf[currentPos] = *pItr;
6129 pItr++;
6132 if (m_StringHeapByteLength == 0)
6133 return "";
6135 int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength);
6136 char* result = stackalloc char[cResult];
6137 Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult);
6138 return new string(result, 0, cResult);
6142 #endregion
6143 #endif
6145 #if !MONO
6146 namespace System.Reflection
6148 // Reliable hashtable thread safe for multiple readers and single writer. Note that the reliability goes together with thread
6149 // safety. Thread safety for multiple readers requires atomic update of the state that also makes makes the table
6150 // reliable in the presence of asynchronous exceptions.
6151 internal struct CerHashtable<K, V> where K : class
6153 private class Table
6155 // Note that m_keys and m_values arrays are immutable to allow lock-free reads. A new instance
6156 // of CerHashtable has to be allocated to grow the size of the hashtable.
6157 internal K[] m_keys;
6158 internal V[] m_values;
6159 internal int m_count;
6161 internal Table(int size)
6163 size = HashHelpers.GetPrime(size);
6164 m_keys = new K[size];
6165 m_values = new V[size];
6168 internal void Insert(K key, V value)
6171 int hashcode = GetHashCodeHelper(key);
6172 if (hashcode < 0)
6173 hashcode = ~hashcode;
6175 K[] keys = m_keys;
6176 int index = hashcode % keys.Length;
6178 while (true)
6180 K hit = keys[index];
6182 if (hit == null)
6184 m_count++;
6185 m_values[index] = value;
6187 // This volatile write has to be last. It is going to publish the result atomically.
6189 // Note that incrementing the count or setting the value does not do any harm without setting the key. The inconsistency will be ignored
6190 // and it will go away completely during next rehash.
6191 Volatile.Write(ref keys[index], key);
6193 break;
6195 else
6197 Contract.Assert(!hit.Equals(key), "Key was already in CerHashtable! Potential ---- (or bug) in the Reflection cache?");
6199 index++;
6200 if (index >= keys.Length)
6201 index -= keys.Length;
6207 private Table m_Table;
6209 private const int MinSize = 7;
6211 private static int GetHashCodeHelper(K key)
6213 string sKey = key as string;
6215 // For strings we don't want the key to differ across domains as CerHashtable might be shared.
6216 if(sKey == null)
6218 return key.GetHashCode();
6221 else
6223 return sKey.GetLegacyNonRandomizedHashCode();
6227 private void Rehash(int newSize)
6229 Table newTable = new Table(newSize);
6231 Table oldTable = m_Table;
6232 if (oldTable != null)
6234 K[] keys = oldTable.m_keys;
6235 V[] values = oldTable.m_values;
6237 for (int i = 0; i < keys.Length; i++)
6239 K key = keys[i];
6241 if (key != null)
6243 newTable.Insert(key, values[i]);
6248 // Publish the new table atomically
6249 Volatile.Write(ref m_Table, newTable);
6252 internal V this[K key]
6256 Table table = m_Table;
6258 if (table != null)
6260 int requiredSize = 2 * (table.m_count + 1);
6261 if (requiredSize >= table.m_keys.Length)
6262 Rehash(requiredSize);
6264 else
6266 Rehash(MinSize);
6269 m_Table.Insert(key, value);
6273 Table table = Volatile.Read(ref m_Table);
6274 if (table == null)
6275 return default(V);
6277 int hashcode = GetHashCodeHelper(key);
6278 if (hashcode < 0)
6279 hashcode = ~hashcode;
6281 K[] keys = table.m_keys;
6282 int index = hashcode % keys.Length;
6284 while (true)
6286 // This volatile read has to be first. It is reading the atomically published result.
6287 K hit = Volatile.Read(ref keys[index]);
6289 if (hit != null)
6291 if (hit.Equals(key))
6292 return table.m_values[index];
6294 index++;
6295 if (index >= keys.Length)
6296 index -= keys.Length;
6298 else
6300 return default(V);
6307 #endif