1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System
.Reflection
;
6 using System
.Globalization
;
7 using System
.Threading
;
8 using System
.Collections
.Generic
;
9 using System
.Runtime
.Serialization
;
10 using System
.Runtime
.CompilerServices
;
11 using System
.Diagnostics
.Contracts
;
12 using System
.Runtime
.InteropServices
;
13 using System
.Diagnostics
;
17 // Keep this in sync with FormatFlags defined in typestring.h
18 internal enum TypeNameFormatFlags
20 FormatBasic
= 0x00000000, // Not a bitmask, simply the tersest flag settings possible
21 FormatNamespace
= 0x00000001, // Include namespace and/or enclosing class names in type names
22 FormatFullInst
= 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
23 FormatAssembly
= 0x00000004, // Include assembly display name in type names
24 FormatSignature
= 0x00000008, // Include signature in method names
25 FormatNoVersion
= 0x00000010, // Suppress version and culture information in all assembly names
27 FormatDebug
= 0x00000020, // For debug printing of types only
29 FormatAngleBrackets
= 0x00000040, // Whether generic types are C<T> or C[T]
30 FormatStubInfo
= 0x00000080, // Include stub info like {unbox-stub}
31 FormatGenericParam
= 0x00000100, // Use !name and !!name for generic type and method parameters
33 // If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
34 // we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
35 // and including the assembly name will normally increase the size of the serialized data and also decrease the performance.
36 FormatSerialization
= FormatNamespace
|
41 internal enum TypeNameKind
49 partial class RuntimeType
53 internal enum MemberListType
61 // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
62 private struct ListBuilder
<T
> where T
: class
69 public ListBuilder(int capacity
)
77 public T
this[int index
]
81 Contract
.Requires(index
< Count
);
82 return (_items
!= null) ? _items
[index
] : _item
;
89 return Array
.Empty
<T
> ();
91 return new T
[1] { _item }
;
93 Array
.Resize(ref _items
, _count
);
98 public void CopyTo(Object
[] array
, int index
)
105 array
[index
] = _item
;
109 Array
.Copy(_items
, 0, array
, index
, _count
);
120 public void Add(T item
)
132 _items
= new T
[_capacity
];
136 if (_capacity
== _count
)
138 int newCapacity
= 2 * _capacity
;
139 Array
.Resize(ref _items
, newCapacity
);
140 _capacity
= newCapacity
;
143 _items
[_count
] = item
;
151 #region Static Members
155 internal static RuntimeType
GetType(String typeName
, bool throwOnError
, bool ignoreCase
, bool reflectionOnly
,
156 ref StackCrawlMark stackMark
)
158 if (typeName
== null)
159 throw new ArgumentNullException("typeName");
160 Contract
.EndContractBlock();
162 return RuntimeTypeHandle
.GetTypeByName(
163 typeName
, throwOnError
, ignoreCase
, reflectionOnly
, ref stackMark
, false);
166 private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type
)
168 if (type
.IsPointer
|| type
.IsByRef
|| type
== typeof(void))
169 throw new ArgumentException(
170 Environment
.GetResourceString("Argument_NeverValidGenericArgument", type
.ToString()));
173 internal static void SanityCheckGenericArguments(RuntimeType
[] genericArguments
, RuntimeType
[] genericParamters
)
175 if (genericArguments
== null)
176 throw new ArgumentNullException();
177 Contract
.EndContractBlock();
179 for(int i
= 0; i
< genericArguments
.Length
; i
++)
181 if (genericArguments
[i
] == null)
182 throw new ArgumentNullException();
184 ThrowIfTypeNeverValidGenericArgument(genericArguments
[i
]);
187 if (genericArguments
.Length
!= genericParamters
.Length
)
188 throw new ArgumentException(
189 Environment
.GetResourceString("Argument_NotEnoughGenArguments", genericArguments
.Length
, genericParamters
.Length
));
192 private static void SplitName(string fullname
, out string name
, out string ns
)
197 if (fullname
== null)
201 int nsDelimiter
= fullname
.LastIndexOf(".", StringComparison
.Ordinal
);
202 if (nsDelimiter
!= -1 )
204 ns
= fullname
.Substring(0, nsDelimiter
);
205 int nameLength
= fullname
.Length
- ns
.Length
- 1;
207 name
= fullname
.Substring(nsDelimiter
+ 1, nameLength
);
210 Contract
.Assert(fullname
.Equals(ns
+ "." + name
));
221 internal static BindingFlags
FilterPreCalculate(bool isPublic
, bool isInherited
, bool isStatic
)
223 BindingFlags bindingFlags
= isPublic
? BindingFlags
.Public
: BindingFlags
.NonPublic
;
227 // We arrange things so the DeclaredOnly flag means "include inherited members"
228 bindingFlags
|= BindingFlags
.DeclaredOnly
;
232 bindingFlags
|= BindingFlags
.Static
| BindingFlags
.FlattenHierarchy
;
236 bindingFlags
|= BindingFlags
.Instance
;
243 bindingFlags
|= BindingFlags
.Static
;
247 bindingFlags
|= BindingFlags
.Instance
;
254 // Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
255 private static void FilterHelper(
256 BindingFlags bindingFlags
, ref string name
, bool allowPrefixLookup
, out bool prefixLookup
,
257 out bool ignoreCase
, out MemberListType listType
)
259 prefixLookup
= false;
264 if ((bindingFlags
& BindingFlags
.IgnoreCase
) != 0)
266 name
= name
.ToLower(CultureInfo
.InvariantCulture
);
268 listType
= MemberListType
.CaseInsensitive
;
272 listType
= MemberListType
.CaseSensitive
;
275 if (allowPrefixLookup
&& name
.EndsWith("*", StringComparison
.Ordinal
))
277 // We set prefixLookup to true if name ends with a "*".
278 // We will also set listType to All so that all members are included in
279 // the candidates which are later filtered by FilterApplyPrefixLookup.
280 name
= name
.Substring(0, name
.Length
- 1);
282 listType
= MemberListType
.All
;
287 listType
= MemberListType
.All
;
291 // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported.
292 private static void FilterHelper(BindingFlags bindingFlags
, ref string name
, out bool ignoreCase
, out MemberListType listType
)
295 FilterHelper(bindingFlags
, ref name
, false, out prefixLookup
, out ignoreCase
, out listType
);
298 // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true.
299 // Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
300 private static bool FilterApplyPrefixLookup(MemberInfo memberInfo
, string name
, bool ignoreCase
)
302 Contract
.Assert(name
!= null);
306 if (!memberInfo
.Name
.StartsWith(name
, StringComparison
.OrdinalIgnoreCase
))
311 if (!memberInfo
.Name
.StartsWith(name
, StringComparison
.Ordinal
))
319 // Used by FilterApplyType to perform all the filtering based on name and BindingFlags
320 private static bool FilterApplyBase(
321 MemberInfo memberInfo
, BindingFlags bindingFlags
, bool isPublic
, bool isNonProtectedInternal
, bool isStatic
,
322 string name
, bool prefixLookup
)
324 #region Preconditions
325 Contract
.Requires(memberInfo
!= null);
326 Contract
.Requires(name
== null || (bindingFlags
& BindingFlags
.IgnoreCase
) == 0 || (name
.ToLower(CultureInfo
.InvariantCulture
).Equals(name
)));
329 #region Filter by Public & Private
332 if ((bindingFlags
& BindingFlags
.Public
) == 0)
337 if ((bindingFlags
& BindingFlags
.NonPublic
) == 0)
342 bool isInherited
= !Object
.ReferenceEquals(memberInfo
.DeclaringType
, memberInfo
.ReflectedType
);
344 #region Filter by DeclaredOnly
345 if ((bindingFlags
& BindingFlags
.DeclaredOnly
) != 0 && isInherited
)
349 #region Filter by Static & Instance
350 if (memberInfo
.MemberType
!= MemberTypes
.TypeInfo
&&
351 memberInfo
.MemberType
!= MemberTypes
.NestedType
)
355 if ((bindingFlags
& BindingFlags
.FlattenHierarchy
) == 0 && isInherited
)
358 if ((bindingFlags
& BindingFlags
.Static
) == 0)
363 if ((bindingFlags
& BindingFlags
.Instance
) == 0)
369 #region Filter by name wrt prefixLookup and implicitly by case sensitivity
370 if (prefixLookup
== true)
372 if (!FilterApplyPrefixLookup(memberInfo
, name
, (bindingFlags
& BindingFlags
.IgnoreCase
) != 0))
378 // @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned
379 // iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
380 if (((bindingFlags
& BindingFlags
.DeclaredOnly
) == 0) && // DeclaredOnly not present
381 isInherited
&& // Is inherited Member
383 (isNonProtectedInternal
) && // Is non-protected internal member
384 ((bindingFlags
& BindingFlags
.NonPublic
) != 0) && // BindingFlag.NonPublic present
386 (!isStatic
) && // Is instance member
387 ((bindingFlags
& BindingFlags
.Instance
) != 0)) // BindingFlag.Instance present
389 MethodInfo methodInfo
= memberInfo
as MethodInfo
;
391 if (methodInfo
== null)
394 if (!methodInfo
.IsVirtual
&& !methodInfo
.IsAbstract
)
403 // Used by GetInterface and GetNestedType(s) which don't need parameter type filtering.
404 private static bool FilterApplyType(
405 Type type
, BindingFlags bindingFlags
, string name
, bool prefixLookup
, string ns
)
407 Contract
.Requires((object)type
!= null);
408 Contract
.Assert(type
is RuntimeType
);
410 bool isPublic
= type
.IsNestedPublic
|| type
.IsPublic
;
411 bool isStatic
= false;
413 if (!FilterApplyBase(type
, bindingFlags
, isPublic
, type
.IsNestedAssembly
, isStatic
, name
, prefixLookup
))
416 if (ns
!= null && ns
!= type
.Namespace
)
423 private static bool FilterApplyMethodInfo(
424 RuntimeMethodInfo method
, BindingFlags bindingFlags
, CallingConventions callConv
, Type
[] argumentTypes
)
426 // Optimization: Pre-Calculate the method binding flags to avoid casting.
427 return FilterApplyMethodBase(method
, method
.BindingFlags
, bindingFlags
, callConv
, argumentTypes
);
430 private static bool FilterApplyConstructorInfo(
431 RuntimeConstructorInfo constructor
, BindingFlags bindingFlags
, CallingConventions callConv
, Type
[] argumentTypes
)
433 // Optimization: Pre-Calculate the method binding flags to avoid casting.
434 return FilterApplyMethodBase(constructor
, constructor
.BindingFlags
, bindingFlags
, callConv
, argumentTypes
);
437 // Used by GetMethodCandidates/GetConstructorCandidates, InvokeMember, and CreateInstanceImpl to perform the necessary filtering.
438 // Should only be called by FilterApplyMethodInfo and FilterApplyConstructorInfo.
439 private static bool FilterApplyMethodBase(
440 MethodBase methodBase
, BindingFlags methodFlags
, BindingFlags bindingFlags
, CallingConventions callConv
, Type
[] argumentTypes
)
442 Contract
.Requires(methodBase
!= null);
444 bindingFlags ^
= BindingFlags
.DeclaredOnly
;
445 #region Check CallingConvention
446 if ((callConv
& CallingConventions
.Any
) == 0)
448 if ((callConv
& CallingConventions
.VarArgs
) != 0 &&
449 (methodBase
.CallingConvention
& CallingConventions
.VarArgs
) == 0)
452 if ((callConv
& CallingConventions
.Standard
) != 0 &&
453 (methodBase
.CallingConvention
& CallingConventions
.Standard
) == 0)
458 #region If argumentTypes supplied
459 if (argumentTypes
!= null)
461 ParameterInfo
[] parameterInfos
= methodBase
.GetParametersNoCopy();
463 if (argumentTypes
.Length
!= parameterInfos
.Length
)
465 #region Invoke Member, Get\Set & Create Instance specific case
466 // If the number of supplied arguments differs than the number in the signature AND
467 // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
469 (BindingFlags
.InvokeMethod
| BindingFlags
.CreateInstance
| BindingFlags
.GetProperty
| BindingFlags
.SetProperty
)) == 0)
472 bool testForParamArray
= false;
473 bool excessSuppliedArguments
= argumentTypes
.Length
> parameterInfos
.Length
;
475 if (excessSuppliedArguments
)
476 { // more supplied arguments than parameters, additional arguments could be vararg
478 // If method is not vararg, additional arguments can not be passed as vararg
479 if ((methodBase
.CallingConvention
& CallingConventions
.VarArgs
) == 0)
481 testForParamArray
= true;
485 // If Binding flags did not include varargs we would have filtered this vararg method.
486 // This Invariant established during callConv check.
487 Contract
.Assert((callConv
& CallingConventions
.VarArgs
) != 0);
492 {// fewer supplied arguments than parameters, missing arguments could be optional
493 #region OptionalParamBinding
494 if ((bindingFlags
& BindingFlags
.OptionalParamBinding
) == 0)
496 testForParamArray
= true;
500 // From our existing code, our policy here is that if a parameterInfo
501 // is optional then all subsequent parameterInfos shall be optional.
503 // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
504 if (!parameterInfos
[argumentTypes
.Length
].IsOptional
)
505 testForParamArray
= true;
511 if (testForParamArray
)
513 if (parameterInfos
.Length
== 0)
516 // The last argument of the signature could be a param array.
517 bool shortByMoreThanOneSuppliedArgument
= argumentTypes
.Length
< parameterInfos
.Length
- 1;
519 if (shortByMoreThanOneSuppliedArgument
)
522 ParameterInfo lastParameter
= parameterInfos
[parameterInfos
.Length
- 1];
524 if (!lastParameter
.ParameterType
.IsArray
)
527 if (!lastParameter
.IsDefined(typeof(ParamArrayAttribute
), false))
536 #region Exact Binding
537 if ((bindingFlags
& BindingFlags
.ExactBinding
) != 0)
539 // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
540 // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
541 // all the rest of this to the binder too? Further, what other semanitc would the binder
542 // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance
543 // in this if statement? That's just InvokeMethod with a constructor, right?
544 if ((bindingFlags
& (BindingFlags
.InvokeMethod
)) == 0)
546 for(int i
= 0; i
< parameterInfos
.Length
; i
++)
548 // a null argument type implies a null arg which is always a perfect match
549 if ((object)argumentTypes
[i
] != null && !argumentTypes
[i
].MatchesParameterTypeExactly(parameterInfos
[i
]))
566 #region Private Data Members
568 internal static readonly RuntimeType ValueType
= (RuntimeType
)typeof(System
.ValueType
);
569 internal static readonly RuntimeType EnumType
= (RuntimeType
)typeof(System
.Enum
);
571 private static readonly RuntimeType ObjectType
= (RuntimeType
)typeof(System
.Object
);
572 private static readonly RuntimeType StringType
= (RuntimeType
)typeof(System
.String
);
573 private static readonly RuntimeType DelegateType
= (RuntimeType
)typeof(System
.Delegate
);
578 internal RuntimeType() { throw new NotSupportedException(); }
581 #region Type Overrides
583 #region Get XXXInfo Candidates
584 private ListBuilder
<MethodInfo
> GetMethodCandidates(
585 String name
, BindingFlags bindingAttr
, CallingConventions callConv
,
586 Type
[] types
, int genericParamCount
, bool allowPrefixLookup
)
588 bool prefixLookup
, ignoreCase
;
589 MemberListType listType
;
590 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
592 RuntimeMethodInfo
[] cache
= GetMethodsByName (name
, bindingAttr
, listType
, this);
593 ListBuilder
<MethodInfo
> candidates
= new ListBuilder
<MethodInfo
>(cache
.Length
);
595 for (int i
= 0; i
< cache
.Length
; i
++)
597 RuntimeMethodInfo methodInfo
= cache
[i
];
598 if (genericParamCount
!= -1) {
599 bool is_generic
= methodInfo
.IsGenericMethod
;
600 if (genericParamCount
== 0 && is_generic
)
602 else if (genericParamCount
> 0 && !is_generic
)
604 var args
= methodInfo
.GetGenericArguments ();
605 if (args
.Length
!= genericParamCount
)
608 if (FilterApplyMethodInfo(methodInfo
, bindingAttr
, callConv
, types
) &&
609 (!prefixLookup
|| FilterApplyPrefixLookup(methodInfo
, name
, ignoreCase
)))
611 candidates
.Add(methodInfo
);
618 private ListBuilder
<ConstructorInfo
> GetConstructorCandidates(
619 string name
, BindingFlags bindingAttr
, CallingConventions callConv
,
620 Type
[] types
, bool allowPrefixLookup
)
622 bool prefixLookup
, ignoreCase
;
623 MemberListType listType
;
624 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
626 if (!string.IsNullOrEmpty (name
) && name
!= ConstructorInfo
.ConstructorName
&& name
!= ConstructorInfo
.TypeConstructorName
)
627 return new ListBuilder
<ConstructorInfo
> (0);
628 RuntimeConstructorInfo
[] cache
= GetConstructors_internal (bindingAttr
, this);
629 ListBuilder
<ConstructorInfo
> candidates
= new ListBuilder
<ConstructorInfo
>(cache
.Length
);
630 for (int i
= 0; i
< cache
.Length
; i
++)
632 RuntimeConstructorInfo constructorInfo
= cache
[i
];
633 if (FilterApplyConstructorInfo(constructorInfo
, bindingAttr
, callConv
, types
) &&
634 (!prefixLookup
|| FilterApplyPrefixLookup(constructorInfo
, name
, ignoreCase
)))
636 candidates
.Add(constructorInfo
);
644 private ListBuilder
<PropertyInfo
> GetPropertyCandidates(
645 String name
, BindingFlags bindingAttr
, Type
[] types
, bool allowPrefixLookup
)
647 bool prefixLookup
, ignoreCase
;
648 MemberListType listType
;
649 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
651 RuntimePropertyInfo
[] cache
= GetPropertiesByName (name
, bindingAttr
, listType
, this);
652 bindingAttr ^
= BindingFlags
.DeclaredOnly
;
654 ListBuilder
<PropertyInfo
> candidates
= new ListBuilder
<PropertyInfo
>(cache
.Length
);
655 for (int i
= 0; i
< cache
.Length
; i
++)
657 RuntimePropertyInfo propertyInfo
= cache
[i
];
658 if ((bindingAttr
& propertyInfo
.BindingFlags
) == propertyInfo
.BindingFlags
&&
659 (!prefixLookup
|| FilterApplyPrefixLookup(propertyInfo
, name
, ignoreCase
)) &&
660 (types
== null || (propertyInfo
.GetIndexParameters().Length
== types
.Length
)))
662 candidates
.Add(propertyInfo
);
669 private ListBuilder
<EventInfo
> GetEventCandidates(String name
, BindingFlags bindingAttr
, bool allowPrefixLookup
)
671 bool prefixLookup
, ignoreCase
;
672 MemberListType listType
;
673 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
675 RuntimeEventInfo
[] cache
= GetEvents_internal (name
, bindingAttr
, listType
, this);
676 bindingAttr ^
= BindingFlags
.DeclaredOnly
;
678 ListBuilder
<EventInfo
> candidates
= new ListBuilder
<EventInfo
>(cache
.Length
);
679 for (int i
= 0; i
< cache
.Length
; i
++)
681 RuntimeEventInfo eventInfo
= cache
[i
];
682 if ((bindingAttr
& eventInfo
.BindingFlags
) == eventInfo
.BindingFlags
&&
683 (!prefixLookup
|| FilterApplyPrefixLookup(eventInfo
, name
, ignoreCase
)))
685 candidates
.Add(eventInfo
);
692 private ListBuilder
<FieldInfo
> GetFieldCandidates(String name
, BindingFlags bindingAttr
, bool allowPrefixLookup
)
694 bool prefixLookup
, ignoreCase
;
695 MemberListType listType
;
696 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
698 RuntimeFieldInfo
[] cache
= GetFields_internal (name
, bindingAttr
, listType
, this);
699 bindingAttr ^
= BindingFlags
.DeclaredOnly
;
701 ListBuilder
<FieldInfo
> candidates
= new ListBuilder
<FieldInfo
>(cache
.Length
);
702 for (int i
= 0; i
< cache
.Length
; i
++)
704 RuntimeFieldInfo fieldInfo
= cache
[i
];
705 if ((bindingAttr
& fieldInfo
.BindingFlags
) == fieldInfo
.BindingFlags
&&
706 (!prefixLookup
|| FilterApplyPrefixLookup(fieldInfo
, name
, ignoreCase
)))
708 candidates
.Add(fieldInfo
);
715 private ListBuilder
<Type
> GetNestedTypeCandidates(String fullname
, BindingFlags bindingAttr
, bool allowPrefixLookup
)
717 bool prefixLookup
, ignoreCase
;
718 bindingAttr
&= ~BindingFlags
.Static
;
720 MemberListType listType
;
721 SplitName(fullname
, out name
, out ns
);
722 FilterHelper(bindingAttr
, ref name
, allowPrefixLookup
, out prefixLookup
, out ignoreCase
, out listType
);
724 RuntimeType
[] cache
= GetNestedTypes_internal (name
, bindingAttr
, listType
);
725 ListBuilder
<Type
> candidates
= new ListBuilder
<Type
>(cache
.Length
);
726 for (int i
= 0; i
< cache
.Length
; i
++)
728 RuntimeType nestedClass
= cache
[i
];
729 if (FilterApplyType(nestedClass
, bindingAttr
, name
, prefixLookup
, ns
))
731 candidates
.Add(nestedClass
);
740 #region Get All XXXInfos
741 public override MethodInfo
[] GetMethods(BindingFlags bindingAttr
)
743 return GetMethodCandidates(null, bindingAttr
, CallingConventions
.Any
, null, -1, false).ToArray();
747 public override ConstructorInfo
[] GetConstructors(BindingFlags bindingAttr
)
749 return GetConstructorCandidates(null, bindingAttr
, CallingConventions
.Any
, null, false).ToArray();
752 public override PropertyInfo
[] GetProperties(BindingFlags bindingAttr
)
754 return GetPropertyCandidates(null, bindingAttr
, null, false).ToArray();
757 public override EventInfo
[] GetEvents(BindingFlags bindingAttr
)
759 return GetEventCandidates(null, bindingAttr
, false).ToArray();
762 public override FieldInfo
[] GetFields(BindingFlags bindingAttr
)
764 return GetFieldCandidates(null, bindingAttr
, false).ToArray();
767 public override Type
[] GetNestedTypes(BindingFlags bindingAttr
)
769 return GetNestedTypeCandidates(null, bindingAttr
, false).ToArray();
772 public override MemberInfo
[] GetMembers(BindingFlags bindingAttr
)
774 ListBuilder
<MethodInfo
> methods
= GetMethodCandidates(null, bindingAttr
, CallingConventions
.Any
, null, -1, false);
775 ListBuilder
<ConstructorInfo
> constructors
= GetConstructorCandidates(null, bindingAttr
, CallingConventions
.Any
, null, false);
776 ListBuilder
<PropertyInfo
> properties
= GetPropertyCandidates(null, bindingAttr
, null, false);
777 ListBuilder
<EventInfo
> events
= GetEventCandidates(null, bindingAttr
, false);
778 ListBuilder
<FieldInfo
> fields
= GetFieldCandidates(null, bindingAttr
, false);
779 ListBuilder
<Type
> nestedTypes
= GetNestedTypeCandidates(null, bindingAttr
, false);
780 // Interfaces are excluded from the result of GetMembers
782 MemberInfo
[] members
= new MemberInfo
[
791 methods
.CopyTo(members
, i
); i
+= methods
.Count
;
792 constructors
.CopyTo(members
, i
); i
+= constructors
.Count
;
793 properties
.CopyTo(members
, i
); i
+= properties
.Count
;
794 events
.CopyTo(members
, i
); i
+= events
.Count
;
795 fields
.CopyTo(members
, i
); i
+= fields
.Count
;
796 nestedTypes
.CopyTo(members
, i
); i
+= nestedTypes
.Count
;
797 Contract
.Assert(i
== members
.Length
);
804 protected override MethodInfo
GetMethodImpl(string name
, BindingFlags bindingAttr
, Binder
? binder
, CallingConventions callConvention
, Type
[]? types
, ParameterModifier
[]? modifiers
)
806 return GetMethodImpl (name
, -1, bindingAttr
, binder
, callConvention
, types
, modifiers
);
809 protected override MethodInfo
GetMethodImpl(String name
, int genericParamCount
,
810 BindingFlags bindingAttr
, Binder
? binder
, CallingConventions callConv
,
811 Type
[]? types
, ParameterModifier
[]? modifiers
)
813 ListBuilder
<MethodInfo
> candidates
= GetMethodCandidates(name
, bindingAttr
, callConv
, types
, genericParamCount
, false);
814 if (candidates
.Count
== 0)
817 if (types
== null || types
.Length
== 0)
819 MethodInfo firstCandidate
= candidates
[0];
821 if (candidates
.Count
== 1)
823 return firstCandidate
;
825 else if (types
== null)
827 for (int j
= 1; j
< candidates
.Count
; j
++)
829 MethodInfo methodInfo
= candidates
[j
];
830 if (!System
.DefaultBinder
.CompareMethodSig (methodInfo
, firstCandidate
))
831 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
834 // All the methods have the exact same name and sig so return the most derived one.
835 return System
.DefaultBinder
.FindMostDerivedNewSlotMeth(candidates
.ToArray(), candidates
.Count
) as MethodInfo
;
840 binder
= DefaultBinder
;
842 return binder
.SelectMethod(bindingAttr
, candidates
.ToArray(), types
, modifiers
) as MethodInfo
;
845 protected override ConstructorInfo
GetConstructorImpl(
846 BindingFlags bindingAttr
, Binder
? binder
, CallingConventions callConvention
,
847 Type
[] types
, ParameterModifier
[]? modifiers
)
849 ListBuilder
<ConstructorInfo
> candidates
= GetConstructorCandidates(null, bindingAttr
, CallingConventions
.Any
, types
, false);
851 if (candidates
.Count
== 0)
854 if (types
.Length
== 0 && candidates
.Count
== 1)
856 ConstructorInfo firstCandidate
= candidates
[0];
858 ParameterInfo
[] parameters
= firstCandidate
.GetParametersNoCopy();
859 if (parameters
== null || parameters
.Length
== 0)
861 return firstCandidate
;
865 if ((bindingAttr
& BindingFlags
.ExactBinding
) != 0)
866 return System
.DefaultBinder
.ExactBinding(candidates
.ToArray(), types
, modifiers
) as ConstructorInfo
;
869 binder
= DefaultBinder
;
871 return binder
.SelectMethod(bindingAttr
, candidates
.ToArray(), types
, modifiers
) as ConstructorInfo
;
875 protected override PropertyInfo
GetPropertyImpl(
876 String name
, BindingFlags bindingAttr
, Binder
? binder
, Type
? returnType
, Type
[]? types
, ParameterModifier
[]? modifiers
)
878 if (name
== null) throw new ArgumentNullException();
879 Contract
.EndContractBlock();
881 ListBuilder
<PropertyInfo
> candidates
= GetPropertyCandidates(name
, bindingAttr
, types
, false);
883 if (candidates
.Count
== 0)
886 if (types
== null || types
.Length
== 0)
889 if (candidates
.Count
== 1)
891 PropertyInfo firstCandidate
= candidates
[0];
893 if ((object)returnType
!= null && !returnType
.IsEquivalentTo(firstCandidate
.PropertyType
))
896 return firstCandidate
;
900 if ((object)returnType
== null)
901 // if we are here we have no args or property type to select over and we have more than one property with that name
902 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
906 if ((bindingAttr
& BindingFlags
.ExactBinding
) != 0)
907 return System
.DefaultBinder
.ExactPropertyBinding(candidates
.ToArray(), returnType
, types
, modifiers
);
910 binder
= DefaultBinder
;
912 return binder
.SelectProperty(bindingAttr
, candidates
.ToArray(), returnType
, types
, modifiers
);
915 public override EventInfo
GetEvent(String name
, BindingFlags bindingAttr
)
917 if (name
== null) throw new ArgumentNullException();
918 Contract
.EndContractBlock();
921 MemberListType listType
;
922 FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
924 RuntimeEventInfo
[] cache
= GetEvents_internal (name
, bindingAttr
, listType
, this);
925 EventInfo match
= null;
927 bindingAttr ^
= BindingFlags
.DeclaredOnly
;
929 for (int i
= 0; i
< cache
.Length
; i
++)
931 RuntimeEventInfo eventInfo
= cache
[i
];
932 if ((bindingAttr
& eventInfo
.BindingFlags
) == eventInfo
.BindingFlags
)
935 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
944 public override FieldInfo
GetField(String name
, BindingFlags bindingAttr
)
946 if (name
== null) throw new ArgumentNullException();
947 Contract
.EndContractBlock();
950 MemberListType listType
;
951 FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
953 RuntimeFieldInfo
[] cache
= GetFields_internal (name
, bindingAttr
, listType
, this);
954 FieldInfo match
= null;
956 bindingAttr ^
= BindingFlags
.DeclaredOnly
;
957 bool multipleStaticFieldMatches
= false;
959 for (int i
= 0; i
< cache
.Length
; i
++)
961 RuntimeFieldInfo fieldInfo
= cache
[i
];
962 if ((bindingAttr
& fieldInfo
.BindingFlags
) == fieldInfo
.BindingFlags
)
966 if (Object
.ReferenceEquals(fieldInfo
.DeclaringType
, match
.DeclaringType
))
967 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
969 if ((match
.DeclaringType
.IsInterface
== true) && (fieldInfo
.DeclaringType
.IsInterface
== true))
970 multipleStaticFieldMatches
= true;
973 if (match
== null || fieldInfo
.DeclaringType
.IsSubclassOf(match
.DeclaringType
) || match
.DeclaringType
.IsInterface
)
978 if (multipleStaticFieldMatches
&& match
.DeclaringType
.IsInterface
)
979 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
984 public override Type
GetInterface(String fullname
, bool ignoreCase
)
986 if (fullname
== null) throw new ArgumentNullException();
987 Contract
.EndContractBlock();
989 BindingFlags bindingAttr
= BindingFlags
.Public
| BindingFlags
.NonPublic
;
991 bindingAttr
&= ~BindingFlags
.Static
;
994 bindingAttr
|= BindingFlags
.IgnoreCase
;
997 MemberListType listType
;
998 SplitName(fullname
, out name
, out ns
);
999 FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
1001 List
<RuntimeType
> list
= null;
1002 var nameComparison
= ignoreCase
? StringComparison
.OrdinalIgnoreCase
: StringComparison
.Ordinal
;
1003 foreach (RuntimeType t
in GetInterfaces ()) {
1005 if (!String
.Equals(t
.Name
, name
, nameComparison
)) {
1010 list
= new List
<RuntimeType
> (2);
1018 var cache
= list
.ToArray ();
1019 RuntimeType match
= null;
1021 for (int i
= 0; i
< cache
.Length
; i
++)
1023 RuntimeType iface
= cache
[i
];
1024 if (FilterApplyType(iface
, bindingAttr
, name
, false, ns
))
1027 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
1036 public override Type
GetNestedType(String fullname
, BindingFlags bindingAttr
)
1038 if (fullname
== null) throw new ArgumentNullException();
1039 Contract
.EndContractBlock();
1042 bindingAttr
&= ~BindingFlags
.Static
;
1044 MemberListType listType
;
1045 SplitName(fullname
, out name
, out ns
);
1046 FilterHelper(bindingAttr
, ref name
, out ignoreCase
, out listType
);
1047 RuntimeType
[] cache
= GetNestedTypes_internal (name
, bindingAttr
, listType
);
1048 RuntimeType match
= null;
1050 for (int i
= 0; i
< cache
.Length
; i
++)
1052 RuntimeType nestedType
= cache
[i
];
1053 if (FilterApplyType(nestedType
, bindingAttr
, name
, false, ns
))
1056 throw new AmbiguousMatchException(Environment
.GetResourceString("Arg_AmbiguousMatchException"));
1065 public override MemberInfo
[] GetMember(String name
, MemberTypes type
, BindingFlags bindingAttr
)
1067 if (name
== null) throw new ArgumentNullException();
1068 Contract
.EndContractBlock();
1070 ListBuilder
<MethodInfo
> methods
= new ListBuilder
<MethodInfo
>();
1071 ListBuilder
<ConstructorInfo
> constructors
= new ListBuilder
<ConstructorInfo
>();
1072 ListBuilder
<PropertyInfo
> properties
= new ListBuilder
<PropertyInfo
>();
1073 ListBuilder
<EventInfo
> events
= new ListBuilder
<EventInfo
>();
1074 ListBuilder
<FieldInfo
> fields
= new ListBuilder
<FieldInfo
>();
1075 ListBuilder
<Type
> nestedTypes
= new ListBuilder
<Type
>();
1080 if ((type
& MemberTypes
.Method
) != 0)
1082 methods
= GetMethodCandidates(name
, bindingAttr
, CallingConventions
.Any
, null, -1, true);
1083 if (type
== MemberTypes
.Method
)
1084 return methods
.ToArray();
1085 totalCount
+= methods
.Count
;
1089 if ((type
& MemberTypes
.Constructor
) != 0)
1091 constructors
= GetConstructorCandidates(name
, bindingAttr
, CallingConventions
.Any
, null, true);
1092 if (type
== MemberTypes
.Constructor
)
1093 return constructors
.ToArray();
1094 totalCount
+= constructors
.Count
;
1098 if ((type
& MemberTypes
.Property
) != 0)
1100 properties
= GetPropertyCandidates(name
, bindingAttr
, null, true);
1101 if (type
== MemberTypes
.Property
)
1102 return properties
.ToArray();
1103 totalCount
+= properties
.Count
;
1107 if ((type
& MemberTypes
.Event
) != 0)
1109 events
= GetEventCandidates(name
, bindingAttr
, true);
1110 if (type
== MemberTypes
.Event
)
1111 return events
.ToArray();
1112 totalCount
+= events
.Count
;
1116 if ((type
& MemberTypes
.Field
) != 0)
1118 fields
= GetFieldCandidates(name
, bindingAttr
, true);
1119 if (type
== MemberTypes
.Field
)
1120 return fields
.ToArray();
1121 totalCount
+= fields
.Count
;
1125 if ((type
& (MemberTypes
.NestedType
| MemberTypes
.TypeInfo
)) != 0)
1127 nestedTypes
= GetNestedTypeCandidates(name
, bindingAttr
, true);
1128 if (type
== MemberTypes
.NestedType
|| type
== MemberTypes
.TypeInfo
)
1129 return nestedTypes
.ToArray();
1130 totalCount
+= nestedTypes
.Count
;
1133 MemberInfo
[] compressMembers
= (type
== (MemberTypes
.Method
| MemberTypes
.Constructor
)) ?
1134 new MethodBase
[totalCount
] : new MemberInfo
[totalCount
];
1137 methods
.CopyTo(compressMembers
, i
); i
+= methods
.Count
;
1138 constructors
.CopyTo(compressMembers
, i
); i
+= constructors
.Count
;
1139 properties
.CopyTo(compressMembers
, i
); i
+= properties
.Count
;
1140 events
.CopyTo(compressMembers
, i
); i
+= events
.Count
;
1141 fields
.CopyTo(compressMembers
, i
); i
+= fields
.Count
;
1142 nestedTypes
.CopyTo(compressMembers
, i
); i
+= nestedTypes
.Count
;
1143 Contract
.Assert(i
== compressMembers
.Length
);
1145 return compressMembers
;
1152 // Reflexive, symmetric, transitive.
1153 public override bool IsEquivalentTo(Type
? other
)
1155 RuntimeType otherRtType
= other
as RuntimeType
;
1156 if ((object)otherRtType
== null)
1159 if (otherRtType
== this)
1162 // It's not worth trying to perform further checks in managed
1163 // as they would lead to FCalls anyway.
1164 return RuntimeTypeHandle
.IsEquivalentTo(this, otherRtType
);
1171 internal bool IsDelegate()
1173 return GetBaseType() == typeof(System
.MulticastDelegate
);
1176 public override bool IsEnum
=> GetBaseType() == EnumType
;
1178 public override GenericParameterAttributes GenericParameterAttributes
1182 if (!IsGenericParameter
)
1183 throw new InvalidOperationException(Environment
.GetResourceString("Arg_NotGenericParameter"));
1184 Contract
.EndContractBlock();
1186 return GetGenericParameterAttributes ();
1194 internal RuntimeType
[] GetGenericArgumentsInternal()
1196 return (RuntimeType
[]) GetGenericArgumentsInternal (true);
1199 public override Type
[] GetGenericArguments()
1201 Type
[] types
= GetGenericArgumentsInternal (false);
1204 types
= Array
.Empty
<Type
> ();
1209 public override Type
MakeGenericType(Type
[] instantiation
)
1211 if (instantiation
== null)
1212 throw new ArgumentNullException("instantiation");
1213 Contract
.EndContractBlock();
1215 RuntimeType
[] instantiationRuntimeType
= new RuntimeType
[instantiation
.Length
];
1217 if (!IsGenericTypeDefinition
)
1218 throw new InvalidOperationException(
1219 Environment
.GetResourceString("Arg_NotGenericTypeDefinition", this));
1221 if (GetGenericArguments().Length
!= instantiation
.Length
)
1222 throw new ArgumentException(Environment
.GetResourceString("Argument_GenericArgsCount"), "instantiation");
1224 for (int i
= 0; i
< instantiation
.Length
; i
++)
1226 Type instantiationElem
= instantiation
[i
];
1227 if (instantiationElem
== null)
1228 throw new ArgumentNullException();
1230 RuntimeType rtInstantiationElem
= instantiationElem
as RuntimeType
;
1232 if (rtInstantiationElem
== null)
1234 if (instantiationElem
.IsSignatureType
)
1235 return MakeGenericSignatureType (this, instantiation
);
1236 Type
[] instantiationCopy
= new Type
[instantiation
.Length
];
1237 for (int iCopy
= 0; iCopy
< instantiation
.Length
; iCopy
++)
1238 instantiationCopy
[iCopy
] = instantiation
[iCopy
];
1239 instantiation
= instantiationCopy
;
1241 throw new NotImplementedException ();
1244 instantiationRuntimeType
[i
] = rtInstantiationElem
;
1247 RuntimeType
[] genericParameters
= GetGenericArgumentsInternal();
1249 SanityCheckGenericArguments(instantiationRuntimeType
, genericParameters
);
1252 ret
= MakeGenericType (this, instantiationRuntimeType
);
1254 throw new TypeLoadException ();
1258 public override int GenericParameterPosition
1262 if (!IsGenericParameter
)
1263 throw new InvalidOperationException(Environment
.GetResourceString("Arg_NotGenericParameter"));
1264 Contract
.EndContractBlock();
1265 return GetGenericParameterPosition ();
1271 #region Invoke Member
1272 private const BindingFlags MemberBindingMask
= (BindingFlags
)0x000000FF;
1273 private const BindingFlags InvocationMask
= (BindingFlags
)0x0000FF00;
1274 private const BindingFlags BinderNonCreateInstance
= BindingFlags
.InvokeMethod
| BinderGetSetField
| BinderGetSetProperty
;
1275 private const BindingFlags BinderGetSetProperty
= BindingFlags
.GetProperty
| BindingFlags
.SetProperty
;
1276 private const BindingFlags BinderSetInvokeProperty
= BindingFlags
.InvokeMethod
| BindingFlags
.SetProperty
;
1277 private const BindingFlags BinderGetSetField
= BindingFlags
.GetField
| BindingFlags
.SetField
;
1278 private const BindingFlags BinderSetInvokeField
= BindingFlags
.SetField
| BindingFlags
.InvokeMethod
;
1279 private const BindingFlags BinderNonFieldGetSet
= (BindingFlags
)0x00FFF300;
1280 private const BindingFlags ClassicBindingMask
=
1281 BindingFlags
.InvokeMethod
| BindingFlags
.GetProperty
| BindingFlags
.SetProperty
|
1282 BindingFlags
.PutDispProperty
| BindingFlags
.PutRefDispProperty
;
1283 private static RuntimeType s_typedRef
= (RuntimeType
)typeof(TypedReference
);
1286 [DebuggerStepThroughAttribute
]
1287 [Diagnostics
.DebuggerHidden
]
1288 public override Object
InvokeMember(
1289 String name
, BindingFlags bindingFlags
, Binder
? binder
, Object
? target
,
1290 Object
?[]? providedArgs
, ParameterModifier
[]? modifiers
, CultureInfo
? culture
, String
[]? namedParams
)
1292 if (IsGenericParameter
)
1293 throw new InvalidOperationException(Environment
.GetResourceString("Arg_GenericParameter"));
1294 Contract
.EndContractBlock();
1296 #region Preconditions
1297 if ((bindingFlags
& InvocationMask
) == 0)
1298 // "Must specify binding flags describing the invoke operation required."
1299 throw new ArgumentException(Environment
.GetResourceString("Arg_NoAccessSpec"),"bindingFlags");
1301 // Provide a default binding mask if none is provided
1302 if ((bindingFlags
& MemberBindingMask
) == 0)
1304 bindingFlags
|= BindingFlags
.Instance
| BindingFlags
.Public
;
1306 if ((bindingFlags
& BindingFlags
.CreateInstance
) == 0)
1307 bindingFlags
|= BindingFlags
.Static
;
1310 // There must not be more named parameters than provided arguments
1311 if (namedParams
!= null)
1313 if (providedArgs
!= null)
1315 if (namedParams
.Length
> providedArgs
.Length
)
1316 // "Named parameter array can not be bigger than argument array."
1317 throw new ArgumentException(Environment
.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
1321 if (namedParams
.Length
!= 0)
1322 // "Named parameter array can not be bigger than argument array."
1323 throw new ArgumentException(Environment
.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
1328 #region Check that any named paramters are not null
1329 if (namedParams
!= null && Array
.IndexOf(namedParams
, null) != -1)
1330 // "Named parameter value must not be null."
1331 throw new ArgumentException(Environment
.GetResourceString("Arg_NamedParamNull"),"namedParams");
1334 int argCnt
= (providedArgs
!= null) ? providedArgs
.Length
: 0;
1336 #region Get a Binder
1338 binder
= DefaultBinder
;
1342 #region Delegate to Activator.CreateInstance
1343 if ((bindingFlags
& BindingFlags
.CreateInstance
) != 0)
1345 if ((bindingFlags
& BindingFlags
.CreateInstance
) != 0 && (bindingFlags
& BinderNonCreateInstance
) != 0)
1346 // "Can not specify both CreateInstance and another access type."
1347 throw new ArgumentException(Environment
.GetResourceString("Arg_CreatInstAccess"),"bindingFlags");
1349 return Activator
.CreateInstance(this, bindingFlags
, binder
, providedArgs
, culture
);
1353 // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
1354 if ((bindingFlags
& (BindingFlags
.PutDispProperty
| BindingFlags
.PutRefDispProperty
)) != 0)
1355 bindingFlags
|= BindingFlags
.SetProperty
;
1359 throw new ArgumentNullException("name");
1361 if (name
.Length
== 0 || name
.Equals(@"[DISPID=0]"))
1363 name
= GetDefaultMemberName();
1367 // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
1373 #region GetField or SetField
1374 bool IsGetField
= (bindingFlags
& BindingFlags
.GetField
) != 0;
1375 bool IsSetField
= (bindingFlags
& BindingFlags
.SetField
) != 0;
1377 if (IsGetField
|| IsSetField
)
1379 #region Preconditions
1383 // "Can not specify both Get and Set on a field."
1384 throw new ArgumentException(Environment
.GetResourceString("Arg_FldSetGet"),"bindingFlags");
1386 if ((bindingFlags
& BindingFlags
.SetProperty
) != 0)
1387 // "Can not specify both GetField and SetProperty."
1388 throw new ArgumentException(Environment
.GetResourceString("Arg_FldGetPropSet"),"bindingFlags");
1392 Contract
.Assert(IsSetField
);
1394 if (providedArgs
== null)
1395 throw new ArgumentNullException("providedArgs");
1397 if ((bindingFlags
& BindingFlags
.GetProperty
) != 0)
1398 // "Can not specify both SetField and GetProperty."
1399 throw new ArgumentException(Environment
.GetResourceString("Arg_FldSetPropGet"),"bindingFlags");
1401 if ((bindingFlags
& BindingFlags
.InvokeMethod
) != 0)
1402 // "Can not specify Set on a Field and Invoke on a method."
1403 throw new ArgumentException(Environment
.GetResourceString("Arg_FldSetInvoke"),"bindingFlags");
1407 #region Lookup Field
1408 FieldInfo selFld
= null;
1409 FieldInfo
[] flds
= GetMember(name
, MemberTypes
.Field
, bindingFlags
) as FieldInfo
[];
1411 Contract
.Assert(flds
!= null);
1413 if (flds
.Length
== 1)
1417 else if (flds
.Length
> 0)
1419 selFld
= binder
.BindToField(bindingFlags
, flds
, IsGetField
? Empty
.Value
: providedArgs
[0], culture
);
1425 #region Invocation on a field
1426 if (selFld
.FieldType
.IsArray
|| Object
.ReferenceEquals(selFld
.FieldType
, typeof(System
.Array
)))
1428 #region Invocation of an array Field
1431 if ((bindingFlags
& BindingFlags
.GetField
) != 0)
1437 idxCnt
= argCnt
- 1;
1442 // Verify that all of the index values are ints
1443 int[] idx
= new int[idxCnt
];
1444 for (int i
=0;i
<idxCnt
;i
++)
1448 idx
[i
] = ((IConvertible
)providedArgs
[i
]).ToInt32(null);
1450 catch (InvalidCastException
)
1452 throw new ArgumentException(Environment
.GetResourceString("Arg_IndexMustBeInt"));
1456 // Set or get the value...
1457 Array a
= (Array
) selFld
.GetValue(target
);
1459 // Set or get the value in the array
1460 if ((bindingFlags
& BindingFlags
.GetField
) != 0)
1462 return a
.GetValue(idx
);
1466 a
.SetValue(providedArgs
[idxCnt
],idx
);
1475 #region Get the field value
1477 throw new ArgumentException(Environment
.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
1479 return selFld
.GetValue(target
);
1484 #region Set the field Value
1486 throw new ArgumentException(Environment
.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
1488 selFld
.SetValue(target
,providedArgs
[0],bindingFlags
,binder
,culture
);
1496 if ((bindingFlags
& BinderNonFieldGetSet
) == 0)
1497 throw new MissingFieldException(FullName
, name
);
1501 #region Caching Logic
1503 bool useCache = false;
1505 // Note that when we add something to the cache, we are careful to ensure
1506 // that the actual providedArgs matches the parameters of the method. Otherwise,
1507 // some default argument processing has occurred. We don't want anyone
1508 // else with the same (insufficient) number of actual arguments to get a
1509 // cache hit because then they would bypass the default argument processing
1510 // and the invocation would fail.
1511 if (bDefaultBinder && namedParams == null && argCnt < 6)
1516 MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
1518 if (invokeMethod != null)
1519 return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
1524 #region Property PreConditions
1525 // @Legacy - This is RTM behavior
1526 bool isGetProperty
= (bindingFlags
& BindingFlags
.GetProperty
) != 0;
1527 bool isSetProperty
= (bindingFlags
& BindingFlags
.SetProperty
) != 0;
1529 if (isGetProperty
|| isSetProperty
)
1531 #region Preconditions
1534 Contract
.Assert(!IsSetField
);
1537 throw new ArgumentException(Environment
.GetResourceString("Arg_PropSetGet"), "bindingFlags");
1541 Contract
.Assert(isSetProperty
);
1543 Contract
.Assert(!IsGetField
);
1545 if ((bindingFlags
& BindingFlags
.InvokeMethod
) != 0)
1546 throw new ArgumentException(Environment
.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
1552 MethodInfo
[] finalists
= null;
1553 MethodInfo finalist
= null;
1555 #region BindingFlags.InvokeMethod
1556 if ((bindingFlags
& BindingFlags
.InvokeMethod
) != 0)
1558 #region Lookup Methods
1559 MethodInfo
[] semiFinalists
= GetMember(name
, MemberTypes
.Method
, bindingFlags
) as MethodInfo
[];
1560 List
<MethodInfo
> results
= null;
1562 for(int i
= 0; i
< semiFinalists
.Length
; i
++)
1564 MethodInfo semiFinalist
= semiFinalists
[i
];
1565 Contract
.Assert(semiFinalist
!= null);
1567 if (!FilterApplyMethodInfo((RuntimeMethodInfo
)semiFinalist
, bindingFlags
, CallingConventions
.Any
, new Type
[argCnt
]))
1570 if (finalist
== null)
1572 finalist
= semiFinalist
;
1576 if (results
== null)
1578 results
= new List
<MethodInfo
>(semiFinalists
.Length
);
1579 results
.Add(finalist
);
1582 results
.Add(semiFinalist
);
1586 if (results
!= null)
1588 Contract
.Assert(results
.Count
> 1);
1589 finalists
= new MethodInfo
[results
.Count
];
1590 results
.CopyTo(finalists
);
1596 Contract
.Assert(finalists
== null || finalist
!= null);
1598 #region BindingFlags.GetProperty or BindingFlags.SetProperty
1599 if (finalist
== null && isGetProperty
|| isSetProperty
)
1601 #region Lookup Property
1602 PropertyInfo
[] semiFinalists
= GetMember(name
, MemberTypes
.Property
, bindingFlags
) as PropertyInfo
[];
1603 List
<MethodInfo
> results
= null;
1605 for(int i
= 0; i
< semiFinalists
.Length
; i
++)
1607 MethodInfo semiFinalist
= null;
1611 semiFinalist
= semiFinalists
[i
].GetSetMethod(true);
1615 semiFinalist
= semiFinalists
[i
].GetGetMethod(true);
1618 if (semiFinalist
== null)
1621 if (!FilterApplyMethodInfo((RuntimeMethodInfo
)semiFinalist
, bindingFlags
, CallingConventions
.Any
, new Type
[argCnt
]))
1624 if (finalist
== null)
1626 finalist
= semiFinalist
;
1630 if (results
== null)
1632 results
= new List
<MethodInfo
>(semiFinalists
.Length
);
1633 results
.Add(finalist
);
1636 results
.Add(semiFinalist
);
1640 if (results
!= null)
1642 Contract
.Assert(results
.Count
> 1);
1643 finalists
= new MethodInfo
[results
.Count
];
1644 results
.CopyTo(finalists
);
1650 if (finalist
!= null)
1653 if (finalists
== null &&
1655 finalist
.GetParametersNoCopy().Length
== 0 &&
1656 (bindingFlags
& BindingFlags
.OptionalParamBinding
) == 0)
1658 //if (useCache && argCnt == props[0].GetParameters().Length)
1659 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
1661 return finalist
.Invoke(target
, bindingFlags
, binder
, providedArgs
, culture
);
1664 if (finalists
== null)
1665 finalists
= new MethodInfo
[] { finalist }
;
1667 if (providedArgs
== null)
1668 providedArgs
= Array
.Empty
<Object
>();
1670 Object state
= null;
1673 MethodBase invokeMethod
= null;
1675 try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
1676 catch(MissingMethodException
) { }
1678 if (invokeMethod
== null)
1679 throw new MissingMethodException(FullName
, name
);
1681 //if (useCache && argCnt == invokeMethod.GetParameters().Length)
1682 // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
1684 Object result
= ((MethodInfo
)invokeMethod
).Invoke(target
, bindingFlags
, binder
, providedArgs
, culture
);
1687 binder
.ReorderArgumentArray(ref providedArgs
, state
);
1693 throw new MissingMethodException(FullName
, name
);
1697 public static bool operator ==(RuntimeType left
, RuntimeType right
)
1699 return object.ReferenceEquals(left
, right
);
1702 public static bool operator !=(RuntimeType left
, RuntimeType right
)
1704 return !object.ReferenceEquals(left
, right
);
1707 #region Legacy Internal
1708 private void CreateInstanceCheckThis()
1710 if (ContainsGenericParameters
)
1711 throw new ArgumentException(
1712 Environment
.GetResourceString("Acc_CreateGenericEx", this));
1713 Contract
.EndContractBlock();
1715 Type elementType
= this.GetRootElementType();
1717 if (Object
.ReferenceEquals(elementType
, typeof(ArgIterator
)))
1718 throw new NotSupportedException(Environment
.GetResourceString("Acc_CreateArgIterator"));
1720 if (Object
.ReferenceEquals(elementType
, typeof(void)))
1721 throw new NotSupportedException(Environment
.GetResourceString("Acc_CreateVoid"));
1724 internal Object
CreateInstanceImpl(
1725 BindingFlags bindingAttr
, Binder binder
, Object
[] args
, CultureInfo culture
)
1727 CreateInstanceCheckThis();
1729 Object server
= null;
1736 args
= Array
.Empty
<Object
> ();
1738 int argCnt
= args
.Length
;
1740 // Without a binder we need to do use the default binder...
1742 binder
= DefaultBinder
;
1744 // deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
1745 // so a call to GetMemberCons would fail
1746 bool publicOnly
= (bindingAttr
& BindingFlags
.NonPublic
) == 0;
1747 bool wrapExceptions
= (bindingAttr
& BindingFlags
.DoNotWrapExceptions
) == 0;
1748 if (argCnt
== 0 && (bindingAttr
& BindingFlags
.Public
) != 0 && (bindingAttr
& BindingFlags
.Instance
) != 0
1751 server
= CreateInstanceDefaultCtor(publicOnly
, false, true, wrapExceptions
);
1755 ConstructorInfo
[] candidates
= GetConstructors(bindingAttr
);
1756 List
<MethodBase
> matches
= new List
<MethodBase
>(candidates
.Length
);
1758 // We cannot use Type.GetTypeArray here because some of the args might be null
1759 Type
[] argsType
= new Type
[argCnt
];
1760 for (int i
= 0; i
< argCnt
; i
++)
1762 if (args
[i
] != null)
1764 argsType
[i
] = args
[i
].GetType();
1768 for(int i
= 0; i
< candidates
.Length
; i
++)
1770 if (FilterApplyConstructorInfo((RuntimeConstructorInfo
)candidates
[i
], bindingAttr
, CallingConventions
.Any
, argsType
))
1771 matches
.Add(candidates
[i
]);
1774 MethodBase
[] cons
= new MethodBase
[matches
.Count
];
1775 matches
.CopyTo(cons
);
1776 if (cons
!= null && cons
.Length
== 0)
1781 throw new MissingMethodException(Environment
.GetResourceString("MissingConstructor_Name", FullName
));
1784 MethodBase invokeMethod
;
1785 Object state
= null;
1789 invokeMethod
= binder
.BindToMethod(bindingAttr
, cons
, ref args
, null, culture
, null, out state
);
1791 catch (MissingMethodException
) { invokeMethod = null; }
1793 if (invokeMethod
== null)
1795 throw new MissingMethodException(Environment
.GetResourceString("MissingConstructor_Name", FullName
));
1798 if (invokeMethod
.GetParametersNoCopy().Length
== 0)
1800 if (args
.Length
!= 0)
1803 Contract
.Assert((invokeMethod
.CallingConvention
& CallingConventions
.VarArgs
) ==
1804 CallingConventions
.VarArgs
);
1805 throw new NotSupportedException(String
.Format(CultureInfo
.CurrentCulture
,
1806 Environment
.GetResourceString("NotSupported_CallToVarArg")));
1810 server
= Activator
.CreateInstance(this, nonPublic
: true, wrapExceptions
: wrapExceptions
);
1814 server
= ((ConstructorInfo
)invokeMethod
).Invoke(bindingAttr
, binder
, args
, culture
);
1816 binder
.ReorderArgumentArray(ref args
, state
);
1829 //Console.WriteLine(server);
1833 // Helper to invoke the default (parameterless) ctor.
1834 // fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
1835 [DebuggerStepThroughAttribute
]
1836 [Diagnostics
.DebuggerHidden
]
1837 internal Object
CreateInstanceDefaultCtor(bool publicOnly
, bool skipCheckThis
, bool fillCache
, bool wrapExceptions
)
1840 throw new NotSupportedException (SR
.NotSupported_ByRefLike
);
1842 return CreateInstanceSlow(publicOnly
, wrapExceptions
, skipCheckThis
, fillCache
);
1848 #region keep in sync with object-internals.h
1849 MonoTypeInfo type_info
;
1854 internal TypeCache Cache
{
1857 LazyInitializer
.EnsureInitialized (ref cache
, () => new TypeCache ());
1863 internal sealed class TypeCache
1865 public Enum
.EnumInfo EnumInfo
;
1866 public TypeCode TypeCode
;
1870 internal RuntimeType (Object obj
)
1872 throw new NotImplementedException ();
1875 internal RuntimeConstructorInfo
GetDefaultConstructor ()
1877 RuntimeConstructorInfo ctor
= null;
1879 if (type_info
== null)
1880 type_info
= new MonoTypeInfo ();
1882 ctor
= type_info
.default_ctor
;
1885 var ctors
= GetConstructors (BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.DeclaredOnly
);
1887 for (int i
= 0; i
< ctors
.Length
; ++i
) {
1888 if (ctors
[i
].GetParametersCount () == 0) {
1889 type_info
.default_ctor
= ctor
= (RuntimeConstructorInfo
) ctors
[i
];
1898 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1899 extern MethodInfo
GetCorrespondingInflatedMethod (MethodInfo generic
);
1901 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1902 extern ConstructorInfo
GetCorrespondingInflatedConstructor (ConstructorInfo generic
);
1904 internal override MethodInfo
GetMethod (MethodInfo fromNoninstanciated
)
1906 if (fromNoninstanciated
== null)
1907 throw new ArgumentNullException ("fromNoninstanciated");
1908 return GetCorrespondingInflatedMethod (fromNoninstanciated
);
1911 internal override ConstructorInfo
GetConstructor (ConstructorInfo fromNoninstanciated
)
1913 if (fromNoninstanciated
== null)
1914 throw new ArgumentNullException ("fromNoninstanciated");
1915 return GetCorrespondingInflatedConstructor (fromNoninstanciated
);
1918 internal override FieldInfo
GetField (FieldInfo fromNoninstanciated
)
1920 /* create sensible flags from given FieldInfo */
1921 BindingFlags flags
= fromNoninstanciated
.IsStatic
? BindingFlags
.Static
: BindingFlags
.Instance
;
1922 flags
|= fromNoninstanciated
.IsPublic
? BindingFlags
.Public
: BindingFlags
.NonPublic
;
1923 return GetField (fromNoninstanciated
.Name
, flags
);
1926 string GetDefaultMemberName ()
1928 object [] att
= GetCustomAttributes (typeof (DefaultMemberAttribute
), true);
1929 return att
.Length
!= 0 ? ((DefaultMemberAttribute
) att
[0]).MemberName
: null;
1932 RuntimeConstructorInfo m_serializationCtor
;
1933 internal RuntimeConstructorInfo
GetSerializationCtor()
1935 if (m_serializationCtor
== null) {
1936 var s_SICtorParamTypes
= new Type
[] { typeof(SerializationInfo), typeof(StreamingContext) }
;
1938 m_serializationCtor
= GetConstructor(
1939 BindingFlags
.Instance
| BindingFlags
.Public
| BindingFlags
.NonPublic
,
1941 CallingConventions
.Any
,
1943 null) as RuntimeConstructorInfo
;
1946 return m_serializationCtor
;
1949 internal Object
CreateInstanceSlow(bool publicOnly
, bool wrapExceptions
, bool skipCheckThis
, bool fillCache
)
1951 //bool bNeedSecurityCheck = true;
1952 //bool bCanBeCached = false;
1953 //bool bSecurityCheckOff = false;
1956 CreateInstanceCheckThis();
1959 // bSecurityCheckOff = true;
1961 return CreateInstanceMono (!publicOnly
, wrapExceptions
);
1964 object CreateInstanceMono (bool nonPublic
, bool wrapExceptions
)
1966 var ctor
= GetDefaultConstructor ();
1967 if (!nonPublic
&& ctor
!= null && !ctor
.IsPublic
) {
1968 throw new MissingMethodException(SR
.Format(SR
.Arg_NoDefCTor
, FullName
));
1972 Type elementType
= this.GetRootElementType();
1973 if (ReferenceEquals (elementType
, typeof (TypedReference
)) || ReferenceEquals (elementType
, typeof (RuntimeArgumentHandle
)))
1974 throw new NotSupportedException (Environment
.GetResourceString ("NotSupported_ContainsStackPtr"));
1977 return CreateInstanceInternal (this);
1979 throw new MissingMethodException ("Default constructor not found for type " + FullName
);
1982 // TODO: .net does more checks in unmanaged land in RuntimeTypeHandle::CreateInstance
1984 throw new MissingMethodException ("Cannot create an abstract class '{0}'.", FullName
);
1987 return ctor
.InternalInvoke (null, null, wrapExceptions
);
1990 internal Object
CheckValue (Object
value, Binder binder
, CultureInfo culture
, BindingFlags invokeAttr
)
1992 bool failed
= false;
1993 var res
= TryConvertToType (value, ref failed
);
1997 if ((invokeAttr
& BindingFlags
.ExactBinding
) == BindingFlags
.ExactBinding
)
1998 throw new ArgumentException(String
.Format(CultureInfo
.CurrentUICulture
, Environment
.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
2000 if (binder
!= null && binder
!= Type
.DefaultBinder
)
2001 return binder
.ChangeType (value, this, culture
);
2003 throw new ArgumentException(String
.Format(CultureInfo
.CurrentUICulture
, Environment
.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
2006 object TryConvertToType (object value, ref bool failed
)
2008 if (IsInstanceOfType (value)) {
2013 var elementType
= GetElementType ();
2014 if (value == null || elementType
.IsInstanceOfType (value)) {
2023 var type
= Enum
.GetUnderlyingType (this);
2024 if (type
== value.GetType ())
2026 var res
= IsConvertibleToPrimitiveType (value, this);
2029 } else if (IsPrimitive
) {
2030 var res
= IsConvertibleToPrimitiveType (value, this);
2033 } else if (IsPointer
) {
2034 var vtype
= value.GetType ();
2035 if (vtype
== typeof (IntPtr
) || vtype
== typeof (UIntPtr
))
2037 if (value is Pointer pointer
) {
2038 Type pointerType
= pointer
.GetPointerType ();
2039 if (pointerType
== this)
2040 return pointer
.GetPointerValue ();
2048 // Binder uses some incompatible conversion rules. For example
2049 // int value cannot be used with decimal parameter but in other
2050 // ways it's more flexible than normal convertor, for example
2051 // long value can be used with int based enum
2052 static object IsConvertibleToPrimitiveType (object value, Type targetType
)
2054 var type
= value.GetType ();
2056 type
= Enum
.GetUnderlyingType (type
);
2057 if (type
== targetType
)
2061 var from = Type
.GetTypeCode (type
);
2062 var to
= Type
.GetTypeCode (targetType
);
2068 return (Char
) (Byte
) value;
2069 case TypeCode
.UInt16
:
2073 case TypeCode
.Int16
:
2076 return (Int16
) (Byte
) value;
2077 case TypeCode
.SByte
:
2078 return (Int16
) (SByte
) value;
2081 case TypeCode
.UInt16
:
2084 return (UInt16
) (Byte
) value;
2089 case TypeCode
.Int32
:
2092 return (Int32
) (Byte
) value;
2093 case TypeCode
.SByte
:
2094 return (Int32
) (SByte
) value;
2096 return (Int32
) (Char
) value;
2097 case TypeCode
.Int16
:
2098 return (Int32
) (Int16
) value;
2099 case TypeCode
.UInt16
:
2100 return (Int32
) (UInt16
) value;
2103 case TypeCode
.UInt32
:
2106 return (UInt32
) (Byte
) value;
2108 return (UInt32
) (Char
) value;
2109 case TypeCode
.UInt16
:
2110 return (UInt32
) (UInt16
) value;
2113 case TypeCode
.Int64
:
2116 return (Int64
) (Byte
) value;
2117 case TypeCode
.SByte
:
2118 return (Int64
) (SByte
) value;
2119 case TypeCode
.Int16
:
2120 return (Int64
) (Int16
) value;
2122 return (Int64
) (Char
) value;
2123 case TypeCode
.UInt16
:
2124 return (Int64
) (UInt16
) value;
2125 case TypeCode
.Int32
:
2126 return (Int64
) (Int32
) value;
2127 case TypeCode
.UInt32
:
2128 return (Int64
) (UInt32
) value;
2131 case TypeCode
.UInt64
:
2134 return (UInt64
) (Byte
) value;
2136 return (UInt64
) (Char
) value;
2137 case TypeCode
.UInt16
:
2138 return (UInt64
) (UInt16
) value;
2139 case TypeCode
.UInt32
:
2140 return (UInt64
) (UInt32
) value;
2143 case TypeCode
.Single
:
2146 return (Single
) (Byte
) value;
2147 case TypeCode
.SByte
:
2148 return (Single
) (SByte
) value;
2149 case TypeCode
.Int16
:
2150 return (Single
) (Int16
) value;
2152 return (Single
) (Char
) value;
2153 case TypeCode
.UInt16
:
2154 return (Single
) (UInt16
) value;
2155 case TypeCode
.Int32
:
2156 return (Single
) (Int32
) value;
2157 case TypeCode
.UInt32
:
2158 return (Single
) (UInt32
) value;
2159 case TypeCode
.Int64
:
2160 return (Single
) (Int64
) value;
2161 case TypeCode
.UInt64
:
2162 return (Single
) (UInt64
) value;
2165 case TypeCode
.Double
:
2168 return (Double
) (Byte
) value;
2169 case TypeCode
.SByte
:
2170 return (Double
) (SByte
) value;
2172 return (Double
) (Char
) value;
2173 case TypeCode
.Int16
:
2174 return (Double
) (Int16
) value;
2175 case TypeCode
.UInt16
:
2176 return (Double
) (UInt16
) value;
2177 case TypeCode
.Int32
:
2178 return (Double
) (Int32
) value;
2179 case TypeCode
.UInt32
:
2180 return (Double
) (UInt32
) value;
2181 case TypeCode
.Int64
:
2182 return (Double
) (Int64
) value;
2183 case TypeCode
.UInt64
:
2184 return (Double
) (UInt64
) value;
2185 case TypeCode
.Single
:
2186 return (Double
) (Single
) value;
2191 // Everything else is rejected
2195 string GetCachedName (TypeNameKind kind
)
2198 case TypeNameKind
.SerializationName
:
2201 throw new NotImplementedException ();
2205 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2206 extern Type
make_array_type (int rank
);
2208 public override Type
MakeArrayType ()
2210 return make_array_type (0);
2213 public override Type
MakeArrayType (int rank
)
2215 if (rank
< 1 || rank
> 255)
2216 throw new IndexOutOfRangeException ();
2217 return make_array_type (rank
);
2220 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2221 extern Type
make_byref_type ();
2223 public override Type
MakeByRefType ()
2226 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
2227 return make_byref_type ();
2230 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2231 static extern Type
MakePointerType (Type type
);
2233 public override Type
MakePointerType ()
2236 throw new TypeLoadException ($"Could not load type '{GetType()}' from assembly '{AssemblyQualifiedName}");
2237 return MakePointerType (this);
2240 public override StructLayoutAttribute
? StructLayoutAttribute
{
2242 return GetStructLayoutAttribute ();
2246 public override bool ContainsGenericParameters
{
2248 if (IsGenericParameter
)
2251 if (IsGenericType
) {
2252 foreach (Type arg
in GetGenericArguments ())
2253 if (arg
.ContainsGenericParameters
)
2258 return GetElementType ().ContainsGenericParameters
;
2264 public override Type
[] GetGenericParameterConstraints ()
2266 if (!IsGenericParameter
)
2267 throw new InvalidOperationException(Environment
.GetResourceString("Arg_NotGenericParameter"));
2269 var paramInfo
= new Mono
.RuntimeGenericParamInfoHandle (RuntimeTypeHandle
.GetGenericParameterInfo (this));
2270 Type
[] constraints
= paramInfo
.Constraints
;
2272 return constraints
?? Array
.Empty
<Type
> ();
2275 internal static object CreateInstanceForAnotherGenericParameter (Type genericType
, RuntimeType genericArgument
)
2277 var gt
= (RuntimeType
) MakeGenericType (genericType
, new Type
[] { genericArgument }
);
2278 var ctor
= gt
.GetDefaultConstructor ();
2279 return ctor
.InternalInvoke (null, null, wrapExceptions
: true);
2282 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2283 static extern Type
MakeGenericType (Type gt
, Type
[] types
);
2285 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2286 internal extern IntPtr
GetMethodsByName_native (IntPtr namePtr
, BindingFlags bindingAttr
, MemberListType listType
);
2288 internal RuntimeMethodInfo
[] GetMethodsByName (string name
, BindingFlags bindingAttr
, MemberListType listType
, RuntimeType reflectedType
)
2290 var refh
= new RuntimeTypeHandle (reflectedType
);
2291 using (var namePtr
= new Mono
.SafeStringMarshal (name
))
2292 using (var h
= new Mono
.SafeGPtrArrayHandle (GetMethodsByName_native (namePtr
.Value
, bindingAttr
, listType
))) {
2294 var a
= new RuntimeMethodInfo
[n
];
2295 for (int i
= 0; i
< n
; i
++) {
2296 var mh
= new RuntimeMethodHandle (h
[i
]);
2297 a
[i
] = (RuntimeMethodInfo
) RuntimeMethodInfo
.GetMethodFromHandleNoGenericCheck (mh
, refh
);
2303 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2304 extern IntPtr
GetPropertiesByName_native (IntPtr name
, BindingFlags bindingAttr
, MemberListType listType
);
2306 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2307 extern IntPtr
GetConstructors_native (BindingFlags bindingAttr
);
2309 RuntimeConstructorInfo
[] GetConstructors_internal (BindingFlags bindingAttr
, RuntimeType reflectedType
)
2311 var refh
= new RuntimeTypeHandle (reflectedType
);
2312 using (var h
= new Mono
.SafeGPtrArrayHandle (GetConstructors_native (bindingAttr
))) {
2314 var a
= new RuntimeConstructorInfo
[n
];
2315 for (int i
= 0; i
< n
; i
++) {
2316 var mh
= new RuntimeMethodHandle (h
[i
]);
2317 a
[i
] = (RuntimeConstructorInfo
) RuntimeMethodInfo
.GetMethodFromHandleNoGenericCheck (mh
, refh
);
2323 RuntimePropertyInfo
[] GetPropertiesByName (string name
, BindingFlags bindingAttr
, MemberListType listType
, RuntimeType reflectedType
)
2325 var refh
= new RuntimeTypeHandle (reflectedType
);
2326 using (var namePtr
= new Mono
.SafeStringMarshal (name
))
2327 using (var h
= new Mono
.SafeGPtrArrayHandle (GetPropertiesByName_native (namePtr
.Value
, bindingAttr
, listType
))) {
2329 var a
= new RuntimePropertyInfo
[n
];
2330 for (int i
= 0; i
< n
; i
++) {
2331 var ph
= new Mono
.RuntimePropertyHandle (h
[i
]);
2332 a
[i
] = (RuntimePropertyInfo
) RuntimePropertyInfo
.GetPropertyFromHandle (ph
, refh
);
2338 public override InterfaceMapping
GetInterfaceMap (Type ifaceType
)
2340 if (IsGenericParameter
)
2341 throw new InvalidOperationException(Environment
.GetResourceString("Arg_GenericParameter"));
2343 if ((object)ifaceType
== null)
2344 throw new ArgumentNullException("ifaceType");
2346 RuntimeType ifaceRtType
= ifaceType
as RuntimeType
;
2348 if (ifaceRtType
== null)
2349 throw new ArgumentException(Environment
.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
2351 InterfaceMapping res
;
2352 if (!ifaceType
.IsInterface
)
2353 throw new ArgumentException ("Argument must be an interface.", "ifaceType");
2355 throw new ArgumentException ("'this' type cannot be an interface itself");
2356 res
.TargetType
= this;
2357 res
.InterfaceType
= ifaceType
;
2358 GetInterfaceMapData (this, ifaceType
, out res
.TargetMethods
, out res
.InterfaceMethods
);
2359 if (res
.TargetMethods
== null)
2360 throw new ArgumentException ("Interface not found", "ifaceType");
2365 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2366 static extern void GetInterfaceMapData (Type t
, Type iface
, out MethodInfo
[] targets
, out MethodInfo
[] methods
);
2368 public override Guid GUID
{
2370 object[] att
= GetCustomAttributes(typeof(System
.Runtime
.InteropServices
.GuidAttribute
), true);
2371 if (att
.Length
== 0)
2373 return new Guid(((System
.Runtime
.InteropServices
.GuidAttribute
)att
[0]).Value
);
2377 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2378 internal extern void GetPacking (out int packing
, out int size
);
2380 public override string ToString()
2382 return getFullName (false, false);
2385 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
2386 static extern object CreateInstanceInternal (Type type
);
2388 public extern override MethodBase
? DeclaringMethod
{
2389 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
2393 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2394 internal extern string getFullName(bool full_name
, bool assembly_qualified
);
2396 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2397 extern Type
[] GetGenericArgumentsInternal (bool runtimeArray
);
2399 GenericParameterAttributes
GetGenericParameterAttributes () {
2400 return (new Mono
.RuntimeGenericParamInfoHandle (RuntimeTypeHandle
.GetGenericParameterInfo (this))).Attributes
;
2403 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2404 extern int GetGenericParameterPosition ();
2406 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2407 extern IntPtr
GetEvents_native (IntPtr name
, MemberListType listType
);
2409 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2410 extern IntPtr
GetFields_native (IntPtr name
, BindingFlags bindingAttr
, MemberListType listType
);
2412 RuntimeFieldInfo
[] GetFields_internal (string name
, BindingFlags bindingAttr
, MemberListType listType
, RuntimeType reflectedType
)
2414 var refh
= new RuntimeTypeHandle (reflectedType
);
2415 using (var namePtr
= new Mono
.SafeStringMarshal (name
))
2416 using (var h
= new Mono
.SafeGPtrArrayHandle (GetFields_native (namePtr
.Value
, bindingAttr
, listType
))) {
2418 var a
= new RuntimeFieldInfo
[n
];
2419 for (int i
= 0; i
< n
; i
++) {
2420 var fh
= new RuntimeFieldHandle (h
[i
]);
2421 a
[i
] = (RuntimeFieldInfo
) FieldInfo
.GetFieldFromHandle (fh
, refh
);
2427 RuntimeEventInfo
[] GetEvents_internal (string name
, BindingFlags bindingAttr
, MemberListType listType
, RuntimeType reflectedType
)
2429 var refh
= new RuntimeTypeHandle (reflectedType
);
2430 using (var namePtr
= new Mono
.SafeStringMarshal (name
))
2431 using (var h
= new Mono
.SafeGPtrArrayHandle (GetEvents_native (namePtr
.Value
, listType
))) {
2433 var a
= new RuntimeEventInfo
[n
];
2434 for (int i
= 0; i
< n
; i
++) {
2435 var eh
= new Mono
.RuntimeEventHandle (h
[i
]);
2436 a
[i
] = (RuntimeEventInfo
) RuntimeEventInfo
.GetEventFromHandle (eh
, refh
);
2442 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2443 public extern override Type
[] GetInterfaces();
2445 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
2446 extern IntPtr
GetNestedTypes_native (IntPtr name
, BindingFlags bindingAttr
, MemberListType listType
);
2448 RuntimeType
[] GetNestedTypes_internal (string displayName
, BindingFlags bindingAttr
, MemberListType listType
)
2450 string internalName
= null;
2451 if (displayName
!= null)
2452 internalName
= displayName
;
2453 using (var namePtr
= new Mono
.SafeStringMarshal (internalName
))
2454 using (var h
= new Mono
.SafeGPtrArrayHandle (GetNestedTypes_native (namePtr
.Value
, bindingAttr
, listType
))) {
2456 var a
= new RuntimeType
[n
];
2457 for (int i
= 0; i
< n
; i
++) {
2458 var th
= new RuntimeTypeHandle (h
[i
]);
2459 a
[i
] = (RuntimeType
) Type
.GetTypeFromHandle (th
);
2465 public override string? AssemblyQualifiedName
{
2467 return getFullName (true, true);
2471 public extern override Type
? DeclaringType
{
2472 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
2476 public extern override string Name
{
2477 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
2481 public extern override string? Namespace
{
2482 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
2486 public override string? FullName
{
2488 // https://bugzilla.xamarin.com/show_bug.cgi?id=57938
2489 if (IsGenericType
&& ContainsGenericParameters
&& !IsGenericTypeDefinition
)
2493 // This doesn't need locking
2494 if (type_info
== null)
2495 type_info
= new MonoTypeInfo ();
2496 if ((fullName
= type_info
.full_name
) == null)
2497 fullName
= type_info
.full_name
= getFullName (true, false);
2503 public sealed override bool HasSameMetadataDefinitionAs (MemberInfo other
) => HasSameMetadataDefinitionAsCore
<RuntimeType
> (other
);
2505 public override bool IsSZArray
{
2508 return IsArray
&& ReferenceEquals (this, GetElementType ().MakeArrayType ());
2512 internal override bool IsUserType
{
2518 public override bool IsSubclassOf(Type type
)
2520 if ((object)type
== null)
2521 throw new ArgumentNullException("type");
2523 RuntimeType rtType
= type
as RuntimeType
;
2527 return RuntimeTypeHandle
.IsSubclassOf (this, rtType
);
2530 private const int DEFAULT_PACKING_SIZE
= 8;
2532 internal StructLayoutAttribute
GetStructLayoutAttribute ()
2534 if (IsInterface
|| HasElementType
|| IsGenericParameter
)
2537 int pack
= 0, size
= 0;
2538 LayoutKind layoutKind
= LayoutKind
.Auto
;
2539 switch (Attributes
& TypeAttributes
.LayoutMask
)
2541 case TypeAttributes
.ExplicitLayout
: layoutKind
= LayoutKind
.Explicit
; break;
2542 case TypeAttributes
.AutoLayout
: layoutKind
= LayoutKind
.Auto
; break;
2543 case TypeAttributes
.SequentialLayout
: layoutKind
= LayoutKind
.Sequential
; break;
2547 CharSet charSet
= CharSet
.None
;
2548 switch (Attributes
& TypeAttributes
.StringFormatMask
)
2550 case TypeAttributes
.AnsiClass
: charSet
= CharSet
.Ansi
; break;
2551 case TypeAttributes
.AutoClass
: charSet
= CharSet
.Auto
; break;
2552 case TypeAttributes
.UnicodeClass
: charSet
= CharSet
.Unicode
; break;
2556 GetPacking (out pack
, out size
);
2558 // Metadata parameter checking should not have allowed 0 for packing size.
2559 // The runtime later converts a packing size of 0 to 8 so do the same here
2560 // because it's more useful from a user perspective.
2562 pack
= DEFAULT_PACKING_SIZE
;
2564 return new StructLayoutAttribute (layoutKind
) { Pack = pack, Size = size, CharSet = charSet }
;
2568 // Contains information about the type which is expensive to compute
2569 [StructLayout (LayoutKind
.Sequential
)]
2570 internal class MonoTypeInfo
{
2571 // this is the displayed form: special characters
2572 // ,+*&*[]\ in the identifier portions of the names
2573 // have been escaped with a leading backslash (\)
2574 public string full_name
;
2575 public RuntimeConstructorInfo default_ctor
;