3 // Copyright (c) Microsoft Corporation. All rights reserved.
9 // <OWNER>Microsoft</OWNER>
11 // Implements System.RuntimeType
13 // ======================================================================================
17 using System
.Reflection
;
18 using System
.Runtime
.ConstrainedExecution
;
19 using System
.Globalization
;
20 using System
.Threading
;
21 using System
.Diagnostics
;
23 using System
.Security
.Permissions
;
25 using System
.Collections
;
26 using System
.Collections
.Generic
;
28 using System
.Runtime
.Serialization
;
29 using System
.Runtime
.CompilerServices
;
30 using System
.Security
;
32 using System
.Runtime
.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
;
40 using MdSigCallingConvention
= System
.Signature
.MdSigCallingConvention
;
41 using RuntimeTypeCache
= System
.RuntimeType
.RuntimeTypeCache
;
43 using System
.Runtime
.InteropServices
;
44 using DebuggerStepThroughAttribute
= System
.Diagnostics
.DebuggerStepThroughAttribute
;
46 using MdToken
= System
.Reflection
.MetadataToken
;
48 using System
.Runtime
.Versioning
;
49 using System
.Diagnostics
.Contracts
;
52 using CustomAttribute
=System
.MonoCustomAttrs
;
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
73 FormatDebug
= 0x00000020, // For debug printing of types only
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
|
87 internal enum TypeNameKind
96 internal partial class RuntimeType
:
97 System
.Reflection
.TypeInfo
, ISerializable
, ICloneable
101 internal enum MemberListType
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
117 public ListBuilder(int capacity
)
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
);
138 _items
[index
] = value;
148 return Array
.Empty
<T
> ();
150 return new T
[1] { _item }
;
152 Array
.Resize(ref _items
, _count
);
157 public void CopyTo(Object
[] array
, int index
)
164 array
[index
] = _item
;
168 Array
.Copy(_items
, 0, array
, index
, _count
);
179 public void Add(T item
)
191 _items
= new T
[_capacity
];
195 if (_capacity
== _count
)
197 int newCapacity
= 2 * _capacity
;
198 Array
.Resize(ref _items
, newCapacity
);
199 _capacity
= newCapacity
;
202 _items
[_count
] = item
;
208 internal class RuntimeTypeCache
210 private const int MAXNAMELEN
= 1024;
213 internal enum CacheType
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
;
237 if (RequiresStringComparison())
239 m_nameHash
= m_name
.HashCaseInsensitive();
243 public bool Match(Utf8String name
)
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());
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());
281 private class MemberInfoCache
<T
> where T
: MemberInfo
283 #region Private Data Members
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
;
297 // This is the strong reference back to the cache
298 private RuntimeTypeCache m_runtimeTypeCache
;
303 [System
.Security
.SecuritySafeCritical
] // auto-generated
305 internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache
)
308 Mda
.MemberInfoCacheCreation();
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
);
336 [System
.Security
.SecuritySafeCritical
] // auto-generated
337 internal MethodBase
AddMethod(RuntimeType declaringType
, RuntimeMethodHandleInternal method
, CacheType cacheType
)
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
);
347 case CacheType
.Method
:
348 list
= (T
[])(object)new RuntimeMethodInfo
[1] {
349 new RuntimeMethodInfo(method
, declaringType
, m_runtimeTypeCache
, methodAttributes
, bindingFlags
, null)
352 case CacheType
.Constructor
:
353 list
= (T
[])(object)new RuntimeConstructorInfo
[1] {
354 new RuntimeConstructorInfo(method
, declaringType
, m_runtimeTypeCache
, methodAttributes
, bindingFlags
)
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
)
392 if (name
== null || name
.Length
== 0 ||
393 (cacheType
== CacheType
.Constructor
&& name
.FirstChar
!= '.' && name
.FirstChar
!= '*'))
395 list
= GetListByName(null, 0, null, 0, listType
, cacheType
);
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
);
415 byte* pUtf8Name
= stackalloc byte[cUtf8Name
];
416 list
= GetListByName(pName
, cNameLen
, pUtf8Name
, cUtf8Name
, listType
, cacheType
);
421 Insert(ref list
, name
, listType
);
426 [System
.Security
.SecurityCritical
] // auto-generated
427 private unsafe T
[] GetListByName(char* pName
, int cNameLen
, byte* pUtf8Name
, int cUtf8Name
, MemberListType listType
, CacheType cacheType
)
430 Encoding
.UTF8
.GetBytes(pName
, cNameLen
, pUtf8Name
, cUtf8Name
);
432 Filter filter
= new Filter(pUtf8Name
, cUtf8Name
, listType
);
437 case CacheType
.Method
:
438 list
= PopulateMethods(filter
);
440 case CacheType
.Field
:
441 list
= PopulateFields(filter
);
443 case CacheType
.Constructor
:
444 list
= PopulateConstructors(filter
);
446 case CacheType
.Property
:
447 list
= PopulateProperties(filter
);
449 case CacheType
.Event
:
450 list
= PopulateEvents(filter
);
452 case CacheType
.NestedType
:
453 list
= PopulateNestedClasses(filter
);
455 case CacheType
.Interface
:
456 list
= PopulateInterfaces(filter
);
459 BCLDebug
.Assert(true, "Invalid CacheType");
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();
478 Monitor
.Enter(this, ref lockTaken
);
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
;
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
;
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)
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
537 MergeWithGlobalList(list
);
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)
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;
571 for (cachedIndex
= 0; cachedIndex
< cachedCount
; cachedIndex
++)
573 T cachedMemberInfo
= cachedMembers
[cachedIndex
];
574 if (cachedMemberInfo
== null)
577 if (newMemberInfo
.CacheEquals(cachedMemberInfo
))
579 list
[i
] = cachedMemberInfo
;
587 if (freeSlotIndex
== 0)
588 freeSlotIndex
= cachedIndex
;
590 if (freeSlotIndex
>= cachedMembers
.Length
)
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.
605 Contract
.Assert(false);
607 newSize
= cachedMembers
.Length
+ 1;
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
;
626 m_allMembers
= cachedMembers
;
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
))
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
)));
654 if (!filter
.Match(RuntimeMethodHandle
.GetUtf8Name(methodHandle
)))
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.
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
);
677 if ((methodAttributes
& MethodAttributes
.RTSpecialName
) != 0)
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
);
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
)));
714 if (!filter
.Match(RuntimeMethodHandle
.GetUtf8Name(methodHandle
)))
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
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)
734 #region Continue if this is a private declared on a base type
735 bool isVirtual
= false;
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
)
758 #region Continue if this is a virtual and is already overridden
762 (methodAttributes
& MethodAttributes
.Abstract
) != 0 ||
763 (methodAttributes
& MethodAttributes
.Virtual
) != 0 ||
764 RuntimeMethodHandle
.GetDeclaringType(methodHandle
) != declaringType
);
766 if (overrides
[methodSlot
] == true)
769 overrides
[methodSlot
] = true;
771 else if (isValueType
)
773 if ((methodAttributes
& (MethodAttributes
.Virtual
| MethodAttributes
.Abstract
)) != 0)
778 Contract
.Assert((methodAttributes
& (MethodAttributes
.Virtual
| MethodAttributes
.Abstract
)) == 0);
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
);
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
);
798 declaringType
= RuntimeTypeHandle
.GetBaseType(declaringType
);
799 } while (declaringType
!= null);
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
)));
828 if (!filter
.Match(RuntimeMethodHandle
.GetUtf8Name(methodHandle
)))
832 MethodAttributes methodAttributes
= RuntimeMethodHandle
.GetAttributes(methodHandle
);
834 Contract
.Assert(!methodHandle
.IsNullHandle());
836 if ((methodAttributes
& MethodAttributes
.RTSpecialName
) == 0)
839 // Constructors should not be virtual or abstract
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
);
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
);
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
);
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
);
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];
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
);
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
)));
957 if (!filter
.Match(RuntimeFieldHandle
.GetUtf8Name(runtimeFieldHandle
)))
961 Contract
.Assert(!runtimeFieldHandle
.IsNullHandle());
963 FieldAttributes fieldAttributes
= RuntimeFieldHandle
.GetAttributes(runtimeFieldHandle
);
964 FieldAttributes fieldAccess
= fieldAttributes
& FieldAttributes
.FieldAccessMask
;
968 if (fieldAccess
== FieldAttributes
.Private
)
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
);
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
))
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
;
1022 bool isPrivate
= fieldAccess
== FieldAttributes
.Private
;
1027 if (filter
.RequiresStringComparison())
1030 name
= scope
.GetName(tkField
);
1032 if (!filter
.Match(name
))
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
);
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
)
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();
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
)))
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
)))
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
);
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
)))
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);
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
)
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
])))
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.
1223 if (filter
.RequiresStringComparison())
1225 if (!filter
.Match(RuntimeTypeHandle
.GetUtf8Name(nestedType
)))
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
);
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
))
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
];
1288 Contract
.Assert(!MdToken
.IsNullToken(tkEvent
));
1289 Contract
.Assert(MdToken
.IsTokenOfType(tkEvent
, MetadataTokenType
.Event
));
1291 if (filter
.RequiresStringComparison())
1294 name
= scope
.GetName(tkEvent
);
1296 if (!filter
.Match(name
))
1300 RuntimeEventInfo eventInfo
= new RuntimeEventInfo(
1301 tkEvent
, declaringType
, m_runtimeTypeCache
, out isPrivate
);
1303 #region Remove Inherited Privates
1304 if (declaringType
!= m_runtimeTypeCache
.GetRuntimeType() && isPrivate
)
1308 #region Remove Duplicates
1309 if (csEventInfos
!= null)
1311 string name
= eventInfo
.Name
;
1313 if (csEventInfos
.GetValueOrDefault(name
) != null)
1316 csEventInfos
[name
] = eventInfo
;
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);
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(
1373 RuntimeType declaringType
,
1374 Dictionary
<String
, List
<RuntimePropertyInfo
>> csPropertyInfos
,
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
))
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
];
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
)));
1413 name
= declaringType
.GetRuntimeModule().MetadataImport
.GetName(tkProperty
);
1415 if (!filter
.Match(name
))
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
)
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)
1457 usedSlots
[slot
] = true;
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
);
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
]);
1501 cache
.Add(propertyInfo
);
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
]);
1532 list
.Add(propertyInfo
);
1537 #region NonPrivate Members
1538 internal T
[] GetMemberList(MemberListType listType
, string name
, CacheType cacheType
)
1544 case MemberListType
.CaseSensitive
:
1545 list
= m_csMemberInfos
[name
];
1549 return Populate(name
, listType
, cacheType
);
1551 case MemberListType
.CaseInsensitive
:
1552 list
= m_cisMemberInfos
[name
];
1556 return Populate(name
, listType
, cacheType
);
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();
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
;
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.
1606 internal RuntimeTypeCache(RuntimeType runtimeType
)
1608 m_typeCode
= TypeCode
.Empty
;
1609 m_runtimeType
= runtimeType
;
1610 m_isGlobal
= RuntimeTypeHandle
.GetModule(runtimeType
).RuntimeType
== runtimeType
;
1614 #region Private Members
1615 private string ConstructName(ref string name
, TypeNameFormatFlags formatFlags
)
1619 name
= new RuntimeTypeHandle(m_runtimeType
).ConstructName(formatFlags
);
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
);
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
;
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
)
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
)
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
);
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();
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
,
1782 CallingConventions
.Any
,
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
))
1811 m_defaultMemberName
= attr
.ConstructorArguments
[0].Value
as string;
1817 return m_defaultMemberName
;
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
;
1834 crmi
= la
.m_methodInstantiations
[rmi
];
1838 crmi
= s_methodInstantiations
[rmi
];
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
);
1854 crmi
= la
.m_methodInstantiations
[rmi
];
1857 la
.m_methodInstantiations
[rmi
] = rmi
;
1861 crmi
= s_methodInstantiations
[rmi
];
1864 s_methodInstantiations
[rmi
] = rmi
;
1871 Monitor
.Exit(s_methodInstantiationsLock
);
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
);
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
);
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
;
1963 cache
= new RemotingTypeCachedData(this);
1964 RemotingTypeCachedData ret
= Interlocked
.CompareExchange(ref m_cachedData
, cache
, null);
1972 #endif //FEATURE_REMOTING
1974 #region Static Members
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"));
1990 return RuntimeTypeHandle
.GetTypeByName(
1991 typeName
, throwOnError
, ignoreCase
, reflectionOnly
, ref stackMark
, false);
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
);
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();
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
)
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
);
2128 if (RuntimeMethodHandle
.IsConstructor(methodHandle
))
2130 // Constructor case: constructors cannot be generic
2131 retval
= reflectedType
.Cache
.GetConstructor(declaredType
, methodHandle
);
2136 if (RuntimeMethodHandle
.HasMethodInstantiation(methodHandle
) && !RuntimeMethodHandle
.IsGenericMethodDefinition(methodHandle
))
2137 retval
= reflectedType
.Cache
.GetGenericMethodInfo(methodHandle
);
2139 retval
= reflectedType
.Cache
.GetMethod(declaredType
, methodHandle
);
2142 GC
.KeepAlive(methodInstantiation
);
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
);
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
);
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
)
2209 Contract
.Assume(false, "Unreachable code");
2210 throw new SystemException();
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
));
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
;
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
);
2281 private static void SplitName(string fullname
, out string name
, out string ns
)
2286 if (fullname
== null)
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
);
2299 Contract
.Assert(fullname
.Equals(ns
+ "." + name
));
2310 internal static BindingFlags
FilterPreCalculate(bool isPublic
, bool isInherited
, bool isStatic
)
2312 BindingFlags bindingFlags
= isPublic
? BindingFlags
.Public
: BindingFlags
.NonPublic
;
2316 // We arrange things so the DeclaredOnly flag means "include inherited members"
2317 bindingFlags
|= BindingFlags
.DeclaredOnly
;
2321 bindingFlags
|= BindingFlags
.Static
| BindingFlags
.FlattenHierarchy
;
2325 bindingFlags
|= BindingFlags
.Instance
;
2332 bindingFlags
|= BindingFlags
.Static
;
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;
2353 if ((bindingFlags
& BindingFlags
.IgnoreCase
) != 0)
2355 name
= name
.ToLower(CultureInfo
.InvariantCulture
);
2357 listType
= MemberListType
.CaseInsensitive
;
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
;
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
)
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);
2395 if (!memberInfo
.Name
.StartsWith(name
, StringComparison
.OrdinalIgnoreCase
))
2400 if (!memberInfo
.Name
.StartsWith(name
, StringComparison
.Ordinal
))
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
)));
2418 #region Filter by Public & Private
2421 if ((bindingFlags
& BindingFlags
.Public
) == 0)
2426 if ((bindingFlags
& BindingFlags
.NonPublic
) == 0)
2431 bool isInherited
= !Object
.ReferenceEquals(memberInfo
.DeclaringType
, memberInfo
.ReflectedType
);
2433 #region Filter by DeclaredOnly
2434 if ((bindingFlags
& BindingFlags
.DeclaredOnly
) != 0 && isInherited
)
2438 #region Filter by Static & Instance
2439 if (memberInfo
.MemberType
!= MemberTypes
.TypeInfo
&&
2440 memberInfo
.MemberType
!= MemberTypes
.NestedType
)
2444 if ((bindingFlags
& BindingFlags
.FlattenHierarchy
) == 0 && isInherited
)
2447 if ((bindingFlags
& BindingFlags
.Static
) == 0)
2452 if ((bindingFlags
& BindingFlags
.Instance
) == 0)
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))
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)
2483 if (!methodInfo
.IsVirtual
&& !methodInfo
.IsAbstract
)
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
))
2505 if (ns
!= null && ns
!= type
.Namespace
)
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
;
2535 #region Apply Base Filter
2536 if ((bindingFlags
& methodFlags
) != methodFlags
)
2540 #region Check CallingConvention
2541 if ((callConv
& CallingConventions
.Any
) == 0)
2543 if ((callConv
& CallingConventions
.VarArgs
) != 0 &&
2544 (methodBase
.CallingConvention
& CallingConventions
.VarArgs
) == 0)
2547 if ((callConv
& CallingConventions
.Standard
) != 0 &&
2548 (methodBase
.CallingConvention
& CallingConventions
.Standard
) == 0)
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.
2564 (BindingFlags
.InvokeMethod
| BindingFlags
.CreateInstance
| BindingFlags
.GetProperty
| BindingFlags
.SetProperty
)) == 0)
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
2573 // If method is not vararg, additional arguments can not be passed as vararg
2574 if ((methodBase
.CallingConvention
& CallingConventions
.VarArgs
) == 0)
2576 testForParamArray
= true;
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);
2587 {// fewer supplied arguments than parameters, missing arguments could be optional
2588 #region OptionalParamBinding
2589 if ((bindingFlags
& BindingFlags
.OptionalParamBinding
) == 0)
2591 testForParamArray
= true;
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;
2606 if (testForParamArray
)
2608 if (parameterInfos
.Length
== 0)
2611 // The last argument of the signature could be a param array.
2612 bool shortByMoreThanOneSuppliedArgument
= argumentTypes
.Length
< parameterInfos
.Length
- 1;
2614 if (shortByMoreThanOneSuppliedArgument
)
2617 ParameterInfo lastParameter
= parameterInfos
[parameterInfos
.Length
- 1];
2619 if (!lastParameter
.ParameterType
.IsArray
)
2622 if (!lastParameter
.IsDefined(typeof(ParamArrayAttribute
), false))
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
2645 if ((object)argumentTypes
[i
] != null && !argumentTypes
[i
].MatchesParameterTypeExactly(parameterInfos
[i
]))
2647 if ((object)argumentTypes
[i
] != null && !Object
.ReferenceEquals(parameterInfos
[i
].ParameterType
, argumentTypes
[i
]))
2665 #region Private Data Members
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
;
2672 private INVOCATION_FLAGS m_invocationFlags
;
2674 internal bool IsNonW8PFrameworkAPI()
2676 if (IsGenericParameter
)
2680 return ((RuntimeType
)GetElementType()).IsNonW8PFrameworkAPI();
2682 if (IsSimpleTypeNonW8PFrameworkAPI())
2685 if (IsGenericType
&& !IsGenericTypeDefinition
)
2687 foreach (Type t
in GetGenericArguments())
2689 if (((RuntimeType
)t
).IsNonW8PFrameworkAPI())
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
))
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
;
2741 internal RuntimeType() { throw new NotSupportedException(); }
2744 #region Private\Internal Members
2746 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
2747 internal override bool CacheEquals(object o
)
2749 RuntimeType m
= o
as RuntimeType
;
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
;
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);
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
)
2800 rt
= rt
.GetBaseType();
2801 } while (rt
!= null);
2806 private string GetDefaultMemberName()
2808 return Cache
.GetDefaultMemberName();
2811 #if !FEATURE_CORECLR
2812 internal RuntimeConstructorInfo
GetSerializationCtor()
2814 return Cache
.GetSerializationCtor();
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
);
2832 RuntimeMethodInfo
[] cache
= GetMethodsByName (name
, bindingAttr
, listType
, this);
2834 RuntimeMethodInfo
[] cache
= Cache
.GetMethodList(listType
, name
);
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
)
2845 else if (genericParamCount
> 0 && !is_generic
)
2847 var args
= methodInfo
.GetGenericArguments ();
2848 if (args
.Length
!= genericParamCount
)
2851 if (FilterApplyMethodInfo(methodInfo
, bindingAttr
, callConv
, types
) &&
2852 (!prefixLookup
|| RuntimeType
.FilterApplyPrefixLookup(methodInfo
, name
, ignoreCase
)))
2854 candidates
.Add(methodInfo
);
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
);
2870 if (!string.IsNullOrEmpty (name
) && name
!= ConstructorInfo
.ConstructorName
&& name
!= ConstructorInfo
.TypeConstructorName
)
2871 return new ListBuilder
<ConstructorInfo
> (0);
2872 RuntimeConstructorInfo
[] cache
= GetConstructors_internal (bindingAttr
, this);
2874 RuntimeConstructorInfo
[] cache
= Cache
.GetConstructorList(listType
, name
);
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
);
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
);
2899 RuntimePropertyInfo
[] cache
= GetPropertiesByName (name
, bindingAttr
, listType
, this);
2901 #if FEATURE_LEGACYNETCF
2902 // Dev11 466969 quirk
2903 IReadOnlyList
<RuntimePropertyInfo
> ambiguousProperties
= null;
2904 RuntimePropertyInfo
[] cache
= Cache
.GetPropertyList(listType
, name
, out ambiguousProperties
);
2906 RuntimePropertyInfo
[] cache
= Cache
.GetPropertyList(listType
, name
);
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
);
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:
2952 // public int Prop { get; set; }
2955 // class FooDerived : FooBase
2957 // private int Prop { get; set; }
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;
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
;
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
);
3017 RuntimeEventInfo
[] cache
= GetEvents_internal (name
, bindingAttr
, listType
, this);
3019 RuntimeEventInfo
[] cache
= Cache
.GetEventList(listType
, name
);
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
);
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
);
3044 RuntimeFieldInfo
[] cache
= GetFields_internal (name
, bindingAttr
, listType
, this);
3046 RuntimeFieldInfo
[] cache
= Cache
.GetFieldList(listType
, name
);
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
);
3064 private ListBuilder
<Type
> GetNestedTypeCandidates(String fullname
, BindingFlags bindingAttr
, bool allowPrefixLookup
)
3066 bool prefixLookup
, ignoreCase
;
3067 bindingAttr
&= ~BindingFlags
.Static
;
3069 MemberListType listType
;
3070 SplitName(fullname
, out name
, out ns
);
3071 RuntimeType
.FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
3074 RuntimeType
[] cache
= GetNestedTypes_internal (name
, bindingAttr
, listType
);
3076 RuntimeType
[] cache
= Cache
.GetNestedTypeList(listType
, name
);
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
);
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();
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
]);
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
[
3148 constructors
.Count
+
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
);
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
;
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)
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
;
3265 binder
= DefaultBinder
;
3267 return binder
.SelectMethod(bindingAttr
, candidates
.ToArray(), types
, modifiers
) as MethodInfo
;
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)
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
;
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)
3312 if (types
== null || types
.Length
== 0)
3315 if (candidates
.Count
== 1)
3317 PropertyInfo firstCandidate
= candidates
[0];
3319 if ((object)returnType
!= null && !returnType
.IsEquivalentTo(firstCandidate
.PropertyType
))
3322 return firstCandidate
;
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
);
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();
3347 MemberListType listType
;
3348 RuntimeType
.FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
3351 RuntimeEventInfo
[] cache
= GetEvents_internal (name
, bindingAttr
, listType
, this);
3353 RuntimeEventInfo
[] cache
= Cache
.GetEventList(listType
, name
);
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
)
3365 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
3374 public override FieldInfo
GetField(String name
, BindingFlags bindingAttr
)
3376 if (name
== null) throw new ArgumentNullException();
3377 Contract
.EndContractBlock();
3380 MemberListType listType
;
3381 RuntimeType
.FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
3384 RuntimeFieldInfo
[] cache
= GetFields_internal (name
, bindingAttr
, listType
, this);
3386 RuntimeFieldInfo
[] cache
= Cache
.GetFieldList(listType
, name
);
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
)
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
)
3412 if (multipleStaticFieldMatches
&& match
.DeclaringType
.IsInterface
)
3413 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
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
;
3428 bindingAttr
|= BindingFlags
.IgnoreCase
;
3431 MemberListType listType
;
3432 SplitName(fullname
, out name
, out ns
);
3433 RuntimeType
.FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
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
)) {
3445 list
= new List
<RuntimeType
> (2);
3453 var cache
= list
.ToArray ();
3455 RuntimeType
[] cache
= Cache
.GetInterfaceList(listType
, name
);
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
))
3465 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
3474 public override Type
GetNestedType(String fullname
, BindingFlags bindingAttr
)
3476 if (fullname
== null) throw new ArgumentNullException();
3477 Contract
.EndContractBlock();
3480 bindingAttr
&= ~BindingFlags
.Static
;
3482 MemberListType listType
;
3483 SplitName(fullname
, out name
, out ns
);
3484 RuntimeType
.FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
3486 RuntimeType
[] cache
= GetNestedTypes_internal (name
, bindingAttr
, listType
);
3488 RuntimeType
[] cache
= Cache
.GetNestedTypeList(listType
, name
);
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
))
3498 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
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
>();
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
;
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
;
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
;
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
;
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
;
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
];
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
;
3593 public override Module Module
3597 return GetRuntimeModule();
3601 internal RuntimeModule
GetRuntimeModule()
3603 return RuntimeTypeHandle
.GetModule(this);
3606 public override Assembly Assembly
3610 return GetRuntimeAssembly();
3614 internal RuntimeAssembly
GetRuntimeAssembly()
3616 return RuntimeTypeHandle
.GetAssembly(this);
3619 public override RuntimeTypeHandle TypeHandle
3623 return new RuntimeTypeHandle(this);
3628 [ReliabilityContract(Consistency
.WillNotCorruptState
, Cer
.Success
)]
3629 internal sealed override RuntimeTypeHandle
GetTypeHandleInternal()
3631 return new RuntimeTypeHandle(this);
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
)
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));
3687 typeCode
= TypeCode
.Object
;
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
;
3695 typeCode
= TypeCode
.Object
;
3699 Cache
.TypeCode
= 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)
3717 return GetMethodBase(RuntimeMethodHandle
.GetDeclaringType(declaringMethod
), declaringMethod
);
3724 [System
.Security
.SecuritySafeCritical
] // auto-generated
3725 public override bool IsInstanceOfType(Object o
)
3727 return RuntimeTypeHandle
.IsInstanceOfType(this, o
);
3731 [System
.Runtime
.InteropServices
.ComVisible(true)]
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
;
3742 RuntimeType baseType
= GetBaseType();
3744 while (baseType
!= null)
3746 if (baseType
== rtType
)
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)
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)
3772 if (Object
.ReferenceEquals(c
, this))
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))
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
))
3806 // For anything else we 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)
3818 if (otherRtType
== this)
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
3831 return GetBaseType();
3835 private RuntimeType
GetBaseType()
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
)
3853 if (constraint
.IsGenericParameter
)
3855 GenericParameterAttributes special
;
3856 special
= constraint
.GenericParameterAttributes
& GenericParameterAttributes
.SpecialConstraintMask
;
3858 if ((special
& GenericParameterAttributes
.ReferenceTypeConstraint
) == 0 &&
3859 (special
& GenericParameterAttributes
.NotNullableValueTypeConstraint
) == 0)
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
;
3877 return RuntimeTypeHandle
.GetBaseType(this);
3880 public override Type UnderlyingSystemType
3890 public override String FullName
3894 return GetCachedName(TypeNameKind
.FullName
);
3898 public override String AssemblyQualifiedName
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)
3908 return Assembly
.CreateQualifiedName(this.Assembly
.FullName
, fullname
);
3912 public override String Namespace
3916 string ns
= Cache
.GetNameSpace();
3918 if (ns
== null || ns
.Length
== 0)
3927 [System
.Security
.SecuritySafeCritical
] // auto-generated
3928 protected override TypeAttributes
GetAttributeFlagsImpl()
3930 return RuntimeTypeHandle
.GetAttributes(this);
3933 public override Guid GUID
3935 [System
.Security
.SecuritySafeCritical
] // auto-generated
3938 Guid result
= new Guid ();
3939 GetGUID(ref result
);
3944 [System
.Security
.SecurityCritical
] // auto-generated
3945 [ResourceExposure(ResourceScope
.None
)]
3946 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
3947 private extern void GetGUID(ref Guid result
);
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
)]
3998 private static extern bool IsWindowsRuntimeObjectType(RuntimeType type
);
4000 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
4002 private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type
);
4004 #endif // FEATURE_COMINTEROP
4007 [System
.Security
.SecuritySafeCritical
] // auto-generated
4008 internal override bool HasProxyAttributeImpl()
4010 return RuntimeTypeHandle
.HasProxyAttribute(this);
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
))
4027 return IsSubclassOf(typeof(ValueType
));
4030 #if !FEATURE_CORECLR
4031 public override bool IsEnum
4035 return GetBaseType() == RuntimeType
.EnumType
;
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();
4055 return GetGenericParameterAttributes ();
4057 GenericParameterAttributes attributes
;
4059 RuntimeTypeHandle
.GetMetadataImport(this).GetGenericParamProps(MetadataToken
, out attributes
);
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(); }
4083 internal override bool IsSzArray
4087 return RuntimeTypeHandle
.IsSzArray(this);
4092 protected override bool IsArrayImpl()
4094 return RuntimeTypeHandle
.IsArray(this);
4097 [System
.Security
.SecuritySafeCritical
] // auto-generated
4098 public override int GetArrayRank()
4101 throw new ArgumentException(Environment
.GetResourceString("Argument_HasToBeArrayClass"));
4103 return RuntimeTypeHandle
.GetArrayRank(this);
4106 public override Type
GetElementType()
4108 return RuntimeTypeHandle
.GetElementType(this);
4113 public override string[] GetEnumNames()
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
);
4129 [SecuritySafeCritical
]
4130 public override Array
GetEnumValues()
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
4141 Array ret
= Array
.CreateInstance(this, values
.Length
);
4143 Array ret
= Array
.UnsafeCreateInstance(this, values
.Length
);
4146 for (int i
= 0; i
< values
.Length
; i
++)
4148 Object val
= Enum
.ToObject(this, values
[i
]);
4149 ret
.SetValue(val
, i
);
4155 public override Type
GetEnumUnderlyingType()
4158 throw new ArgumentException(Environment
.GetResourceString("Arg_MustBeEnum"), "enumType");
4159 Contract
.EndContractBlock();
4161 return Enum
.InternalGetUnderlyingType(this);
4164 public override bool IsEnumDefined(object value)
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)
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);
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()));
4215 throw new InvalidOperationException(Environment
.GetResourceString("InvalidOperation_UnknownEnumType"));
4219 public override string GetEnumName(object value)
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
);
4236 string[] names
= Enum
.InternalGetNames(this);
4237 return names
[index
];
4246 internal RuntimeType
[] GetGenericArgumentsInternal()
4249 return (RuntimeType
[]) GetGenericArgumentsInternal (true);
4251 return GetRootElementType().GetTypeHandleInternal().GetInstantiationInternal();
4255 public override Type
[] GetGenericArguments()
4258 Type
[] types
= GetGenericArgumentsInternal (false);
4260 Type
[] types
= GetRootElementType().GetTypeHandleInternal().GetInstantiationPublic();
4264 types
= Array
.Empty
<Type
> ();
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)
4296 if (instantiationElem
.IsSignatureType
)
4297 return MakeGenericSignatureType (this, instantiation
);
4299 Type
[] instantiationCopy
= new Type
[instantiation
.Length
];
4300 for (int iCopy
= 0; iCopy
< instantiation
.Length
; iCopy
++)
4301 instantiationCopy
[iCopy
] = instantiation
[iCopy
];
4302 instantiation
= instantiationCopy
;
4304 throw new NotImplementedException ();
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
4314 instantiationRuntimeType
[i
] = rtInstantiationElem
;
4317 RuntimeType
[] genericParameters
= GetGenericArgumentsInternal();
4319 SanityCheckGenericArguments(instantiationRuntimeType
, genericParameters
);
4323 ret
= MakeGenericType (this, instantiationRuntimeType
);
4325 throw new TypeLoadException ();
4329 ret
= new RuntimeTypeHandle(this).Instantiate(instantiationRuntimeType
);
4331 catch (TypeLoadException e
)
4333 ValidateGenericArguments(this, instantiationRuntimeType
, e
);
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
4354 if (!IsGenericParameter
)
4355 throw new InvalidOperationException(Environment
.GetResourceString("Arg_NotGenericParameter"));
4356 Contract
.EndContractBlock();
4358 return GetGenericParameterPosition ();
4360 return new RuntimeTypeHandle(this).GetGenericVariableIndex();
4365 public override Type
GetGenericTypeDefinition()
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; }
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
;
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
)
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
4423 return (StructLayoutAttribute
)StructLayoutAttribute
.GetCustomAttribute(this);
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
);
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
);
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();
4475 type
= value.GetType();
4478 type
= value.GetType();
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);
4492 // if this is a ByRef get the element type and check if it's compatible
4493 bool isByRef
= 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)
4505 else if (this == s_typedRef
)
4506 // everything works for a typedref
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();
4521 valueType
= (RuntimeType
)value.GetType();
4523 if (CanValueSpecialCast(valueType
, this))
4525 if (pointer
!= null)
4526 return pointer
.GetPointerValue();
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))
4547 // if this is a ByRef get the element type and check if it's compatible
4550 RuntimeType elementType
= RuntimeTypeHandle
.GetElementType(this);
4551 if (elementType
.IsInstanceOfType(value) || value == null)
4552 return AllocateValueType(elementType
, value, false);
4554 else if (value == null)
4556 if (needsSpecialCast
)
4558 RuntimeType valueType
;
4559 Pointer pointer
= value as Pointer
;
4560 if (pointer
!= null)
4561 valueType
= pointer
.GetPointerType();
4563 valueType
= (RuntimeType
)value.GetType();
4565 if (CanValueSpecialCast(valueType
, this))
4567 if (pointer
!= null)
4568 return pointer
.GetPointerValue();
4575 throw new ArgumentException(String
.Format(CultureInfo
.CurrentUICulture
, Environment
.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
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
> ();
4597 #if FEATURE_COMINTEROP
4598 [System
.Security
.SecuritySafeCritical
] // auto-generated
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");
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");
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");
4666 #if FEATURE_REMOTING
4667 if(!RemotingServices
.IsTransparentProxy(target
))
4670 #region Non-TransparentProxy case
4672 throw new ArgumentNullException("name");
4674 throw new NotImplementedException ();
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
);
4685 #if FEATURE_REMOTING
4689 throw new NotImplementedException ();
4691 #region TransparentProxy case
4692 return ((MarshalByRefObject
)target
).InvokeMember(name
, bindingFlags
, binder
, providedArgs
, modifiers
, culture
, namedParams
);
4696 #endif // FEATURE_REMOTING
4698 #endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
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");
4707 int argCnt
= (providedArgs
!= null) ? providedArgs
.Length
: 0;
4709 #region Get a Binder
4711 binder
= DefaultBinder
;
4714 bool bDefaultBinder
= (binder
== DefaultBinder
);
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
);
4729 // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
4730 if ((bindingFlags
& (BindingFlags
.PutDispProperty
| BindingFlags
.PutRefDispProperty
)) != 0)
4731 bindingFlags
|= BindingFlags
.SetProperty
;
4735 throw new ArgumentNullException("name");
4737 if (name
.Length
== 0 || name
.Equals(@"[DISPID=0]"))
4739 name
= GetDefaultMemberName();
4743 // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
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
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");
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");
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)
4793 else if (flds
.Length
> 0)
4795 selFld
= binder
.BindToField(bindingFlags
, flds
, IsGetField
? Empty
.Value
: providedArgs
[0], culture
);
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
4807 if ((bindingFlags
& BindingFlags
.GetField
) != 0)
4813 idxCnt
= argCnt
- 1;
4818 // Verify that all of the index values are ints
4819 int[] idx
= new int[idxCnt
];
4820 for (int i
=0;i
<idxCnt
;i
++)
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
);
4842 a
.SetValue(providedArgs
[idxCnt
],idx
);
4851 #region Get the field value
4853 throw new ArgumentException(Environment
.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
4855 return selFld
.GetValue(target
);
4860 #region Set the field Value
4862 throw new ArgumentException(Environment
.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
4864 selFld
.SetValue(target
,providedArgs
[0],bindingFlags
,binder
,culture
);
4872 if ((bindingFlags
& BinderNonFieldGetSet
) == 0)
4873 throw new MissingFieldException(FullName
, name
);
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)
4892 MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
4894 if (invokeMethod != null)
4895 return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
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
4910 Contract
.Assert(!IsSetField
);
4913 throw new ArgumentException(Environment
.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4917 Contract
.Assert(isSetProperty
);
4919 Contract
.Assert(!IsGetField
);
4921 if ((bindingFlags
& BindingFlags
.InvokeMethod
) != 0)
4922 throw new ArgumentException(Environment
.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
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
]))
4946 if (finalist
== null)
4948 finalist
= semiFinalist
;
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
);
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;
4987 semiFinalist
= semiFinalists
[i
].GetSetMethod(true);
4991 semiFinalist
= semiFinalists
[i
].GetGetMethod(true);
4994 if (semiFinalist
== null)
4997 if (!FilterApplyMethodInfo((RuntimeMethodInfo
)semiFinalist
, bindingFlags
, CallingConventions
.Any
, new Type
[argCnt
]))
5000 if (finalist
== null)
5002 finalist
= semiFinalist
;
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
);
5026 if (finalist
!= null)
5029 if (finalists
== null &&
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
);
5063 binder
.ReorderArgumentArray(ref providedArgs
, state
);
5069 throw new MissingMethodException(FullName
, name
);
5073 #region Object Overrides
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);
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
5100 public override String
ToString()
5102 return GetCachedName(TypeNameKind
.ToString
);
5108 public Object
Clone()
5114 #region ISerializable
5115 [System
.Security
.SecurityCritical
] // auto-generated
5116 public void GetObjectData(SerializationInfo info
, StreamingContext context
)
5119 throw new ArgumentNullException("info");
5120 Contract
.EndContractBlock();
5123 throw new NotImplementedException ();
5125 UnitySerializationHolder
.GetUnitySerializationInfo(info
, this);
5130 #region ICustomAttributeProvider
5131 [System
.Security
.SecuritySafeCritical
] // auto-generated
5132 public override Object
[] GetCustomAttributes(bool inherit
)
5135 return CustomAttribute
.GetCustomAttributes(this, inherit
);
5137 return CustomAttribute
.GetCustomAttributes(this, RuntimeType
.ObjectType
, inherit
);
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);
5177 #region MemberInfo Overrides
5179 public override String Name
5183 return GetCachedName(TypeNameKind
.Name
);
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
)
5200 return GetCachedName(TypeNameKind
.SerializationName
);
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
)
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
);
5228 private string GetCachedName(TypeNameKind kind
)
5230 return Cache
.GetName(kind
);
5233 public override MemberTypes MemberType
5237 if (this.IsPublic
|| this.IsNotPublic
)
5238 return MemberTypes
.TypeInfo
;
5240 return MemberTypes
.NestedType
;
5244 public override Type DeclaringType
5248 return Cache
.GetEnclosingType();
5252 public override Type ReflectedType
5256 return DeclaringType
;
5260 public override int MetadataToken
5262 [System
.Security
.SecuritySafeCritical
] // auto-generated
5265 return RuntimeTypeHandle
.GetToken(this);
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
5294 ,Object
[] activationAttributes
,
5295 ref StackCrawlMark stackMark
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
);
5319 args
= Array
.Empty
<Object
> ();
5321 int argCnt
= args
.Length
;
5323 // Without a binder we need to do use the default binder...
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
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)
5368 // Null out activation attributes before throwing exception
5369 #if FEATURE_REMOTING
5370 if(null != activationAttributes
)
5372 ActivationServices
.PopActivationAttributes(this);
5373 activationAttributes
= null;
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;
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.
5411 if (RuntimeType
.DelegateType
.IsAssignableFrom(invokeMethod
.DeclaringType
))
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
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
);
5450 server
= Activator
.CreateInstance(this, nonPublic
: true, wrapExceptions
: wrapExceptions
);
5451 #if MONO && FEATURE_REMOTING
5457 #if MONO && FEATURE_REMOTING
5459 if (activationAttributes
!= null && activationAttributes
.Length
!= 0) {
5460 server
= ActivationCreateInstance (invokeMethod
, bindingAttr
, binder
, args
, culture
, activationAttributes
);
5463 server
= ((ConstructorInfo
)invokeMethod
).Invoke(bindingAttr
, binder
, args
, culture
);
5464 #if MONO && FEATURE_REMOTING
5469 binder
.ReorderArgumentArray(ref args
, state
);
5475 #if FEATURE_REMOTING
5476 // Reset the TLS to null
5477 if(null != activationAttributes
)
5479 ActivationServices
.PopActivationAttributes(this);
5480 activationAttributes
= null;
5490 //Console.WriteLine(server);
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
);
5506 invokeMethod
.Invoke (server
, bindingAttr
, binder
, args
, culture
);
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
)
5530 m_bNeedSecurityCheck
= bNeedSecurityCheck
;
5531 m_hCtorMethodHandle
= rmh
;
5532 if (!m_hCtorMethodHandle
.IsNullHandle())
5533 m_ctorAttributes
= RuntimeMethodHandle
.GetAttributes(m_hCtorMethodHandle
);
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) }
);
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
);
5590 index
= (index
+1)&(ActivatorCache
.CACHE_SIZE
-1);
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
5610 , ref StackCrawlMark stackMark
5614 RuntimeMethodHandleInternal runtime_ctor
= default(RuntimeMethodHandleInternal
);
5615 bool bNeedSecurityCheck
= true;
5616 bool bCanBeCached
= false;
5617 bool bSecurityCheckOff
= false;
5620 CreateInstanceCheckThis();
5623 bSecurityCheckOff
= true;
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;
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
;
5653 ActivatorCacheEntry ace
= new ActivatorCacheEntry(this, runtime_ctor
, bNeedSecurityCheck
);
5654 activatorCache
.SetEntry(ace
);
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
5667 , ref StackCrawlMark stackMark
5673 throw new NotSupportedException (SR
.NotSupported_ByRefLike
);
5676 if (GetType() == typeof(ReflectionOnlyType
))
5677 throw new InvalidOperationException(Environment
.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5679 ActivatorCache activatorCache
= s_ActivatorCache
;
5680 if (activatorCache
!= null)
5682 ActivatorCacheEntry ace
= activatorCache
.GetEntry(this);
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
);
5713 throw new TargetInvocationException(e
);
5720 return CreateInstanceSlow(publicOnly
, wrapExceptions
, skipCheckThis
, fillCache
, ref stackMark
);
5722 return CreateInstanceSlow(publicOnly
, wrapExceptions
, skipCheckThis
, fillCache
);
5727 internal void InvalidateCachedNestedType()
5729 Cache
.InvalidateCachedNestedType();
5732 [System
.Security
.SecuritySafeCritical
] // auto-generated
5733 internal bool IsGenericCOMObjectImpl()
5735 return RuntimeTypeHandle
.IsComObject(this, true);
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
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;
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.
5808 ParameterModifier paramMod
= new ParameterModifier(cArgs
);
5809 for (int i
= 0; i
< cArgs
; i
++)
5811 if (aParams
[i
].ParameterType
.IsByRef
)
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
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.
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.
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)
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
);
5887 case DispatchWrapperType
.Dispatch
:
5888 wrapperType
= typeof(DispatchWrapper
);
5890 case DispatchWrapperType
.Error
:
5891 wrapperType
= typeof(ErrorWrapper
);
5893 case DispatchWrapperType
.Currency
:
5894 wrapperType
= typeof(CurrencyWrapper
);
5896 case DispatchWrapperType
.BStr
:
5897 wrapperType
= typeof(BStrWrapper
);
5901 Contract
.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
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
;
5914 wrapperCons
= wrapperType
.GetConstructor(new Type
[] {typeof(String)}
);
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
++)
5926 newArray
[currElem
] = wrapperCons
.Invoke(new Object
[] {(String)oldArray.GetValue(currElem)}
);
5930 newArray
[currElem
] = wrapperCons
.Invoke(new Object
[] {oldArray.GetValue(currElem)}
);
5934 // Update the argument.
5935 aArgs
[i
] = newArray
;
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
]);
5945 case DispatchWrapperType
.Dispatch
:
5946 aArgs
[i
] = new DispatchWrapper(aArgs
[i
]);
5948 case DispatchWrapperType
.Error
:
5949 aArgs
[i
] = new ErrorWrapper(aArgs
[i
]);
5951 case DispatchWrapperType
.Currency
:
5952 aArgs
[i
] = new CurrencyWrapper(aArgs
[i
]);
5954 case DispatchWrapperType
.BStr
:
5955 aArgs
[i
] = new BStrWrapper((String
)aArgs
[i
]);
5958 Contract
.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified.");
5965 private OleAutBinder ForwardCallBinder
5969 // Synchronization is not required.
5970 if (s_ForwardCallBinder
== null)
5971 s_ForwardCallBinder
= new OleAutBinder();
5973 return s_ForwardCallBinder
;
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,
5985 Currency
= 0x00000010,
5987 SafeArray
= 0x00010000
5990 private static volatile OleAutBinder s_ForwardCallBinder
;
5991 #endif // FEATURE_COMINTEROP && FEATURE_REMOTING
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
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
6005 internal class ReflectionOnlyType
: RuntimeType
{
6007 private ReflectionOnlyType() {}
6010 public override RuntimeTypeHandle TypeHandle
6014 throw new InvalidOperationException(Environment
.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
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
)
6047 byte* pItr
= (byte*)pUtf8String
;
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
);
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
);
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
);
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()
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
;
6132 if (m_StringHeapByteLength
== 0)
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
);
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
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
);
6173 hashcode
= ~hashcode
;
6176 int index
= hashcode
% keys
.Length
;
6180 K hit
= keys
[index
];
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
);
6197 Contract
.Assert(!hit
.Equals(key
), "Key was already in CerHashtable! Potential ---- (or bug) in the Reflection cache?");
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.
6218 return key
.GetHashCode();
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
++)
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
;
6260 int requiredSize
= 2 * (table
.m_count
+ 1);
6261 if (requiredSize
>= table
.m_keys
.Length
)
6262 Rehash(requiredSize
);
6269 m_Table
.Insert(key
, value);
6273 Table table
= Volatile
.Read(ref m_Table
);
6277 int hashcode
= GetHashCodeHelper(key
);
6279 hashcode
= ~hashcode
;
6281 K
[] keys
= table
.m_keys
;
6282 int index
= hashcode
% keys
.Length
;
6286 // This volatile read has to be first. It is reading the atomically published result.
6287 K hit
= Volatile
.Read(ref keys
[index
]);
6291 if (hit
.Equals(key
))
6292 return table
.m_values
[index
];
6295 if (index
>= keys
.Length
)
6296 index
-= keys
.Length
;