3 // Copyright(c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
9 namespace System.Reflection
12 using System.Collections.Generic;
13 using System.Diagnostics;
14 using System.Diagnostics.Contracts;
15 using System.Globalization;
17 using System.Runtime.InteropServices;
18 using System.Runtime.ConstrainedExecution;
20 using System.Runtime.Remoting.Metadata;
21 #endif //FEATURE_REMOTING
22 using System.Runtime.Serialization;
23 using System.Security;
24 using System.Security.Permissions;
26 using System.Threading;
27 using MemberListType = System.RuntimeType.MemberListType;
29 using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
31 using System.Runtime.CompilerServices;
34 [ClassInterface(ClassInterfaceType.None)]
35 [ComDefaultInterface(typeof(_MethodInfo))]
36 #pragma warning disable 618
37 [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
38 #pragma warning restore 618
39 [System.Runtime.InteropServices.ComVisible(true)]
40 public abstract class MethodInfo : MethodBase
46 protected MethodInfo() { }
50 public static bool operator ==(MethodInfo left, MethodInfo right)
52 if (ReferenceEquals(left, right))
55 if ((object)left == null || (object)right == null ||
56 left is RuntimeMethodInfo || right is RuntimeMethodInfo)
60 return left.Equals(right);
63 public static bool operator !=(MethodInfo left, MethodInfo right)
65 return !(left == right);
67 #endif // !FEATURE_CORECLR
69 public override bool Equals(object obj)
71 return base.Equals(obj);
74 public override int GetHashCode()
76 return base.GetHashCode();
79 #region MemberInfo Overrides
80 public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Method; } }
83 #region Public Abstract\Virtual Members
84 public virtual Type ReturnType { get { throw new NotImplementedException(); } }
86 public virtual ParameterInfo ReturnParameter { get { throw new NotImplementedException(); } }
88 public abstract ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
90 public abstract MethodInfo GetBaseDefinition();
92 [System.Runtime.InteropServices.ComVisible(true)]
93 public override Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
95 [System.Runtime.InteropServices.ComVisible(true)]
96 public virtual MethodInfo GetGenericMethodDefinition() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
98 public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
100 public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
101 public virtual Delegate CreateDelegate(Type delegateType, Object target) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
104 #if !FEATURE_CORECLR && !MOBILE
105 Type _MethodInfo.GetType()
107 return base.GetType();
110 void _MethodInfo.GetTypeInfoCount(out uint pcTInfo)
112 throw new NotImplementedException();
115 void _MethodInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
117 throw new NotImplementedException();
120 void _MethodInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
122 throw new NotImplementedException();
125 // If you implement this method, make sure to include _MethodInfo.Invoke in VM\DangerousAPIs.h and
126 // include _MethodInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
127 void _MethodInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
129 throw new NotImplementedException();
134 // TODO: Remove, needed only for MonoCustomAttribute
135 internal virtual MethodInfo GetBaseMethod ()
144 internal sealed class RuntimeMethodInfo : MethodInfo, ISerializable, IRuntimeMethodInfo
146 #region Private Data Members
147 private IntPtr m_handle;
148 private RuntimeTypeCache m_reflectedTypeCache;
149 private string m_name;
150 private string m_toString;
151 private ParameterInfo[] m_parameters;
152 private ParameterInfo m_returnParameter;
153 private BindingFlags m_bindingFlags;
154 private MethodAttributes m_methodAttributes;
155 private Signature m_signature;
156 private RuntimeType m_declaringType;
157 private object m_keepalive;
158 private INVOCATION_FLAGS m_invocationFlags;
161 private bool IsNonW8PFrameworkAPI()
163 if (m_declaringType.IsArray && IsPublic && !IsStatic)
166 RuntimeAssembly rtAssembly = GetRuntimeAssembly();
167 if (rtAssembly.IsFrameworkAssembly())
169 int ctorToken = rtAssembly.InvocableAttributeCtorToken;
170 if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
171 !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
175 if (GetRuntimeType().IsNonW8PFrameworkAPI())
178 if (IsGenericMethod && !IsGenericMethodDefinition)
180 foreach (Type t in GetGenericArguments())
182 if (((RuntimeType)t).IsNonW8PFrameworkAPI())
190 internal override bool IsDynamicallyInvokable
194 return !AppDomain.ProfileAPICheck || !IsNonW8PFrameworkAPI();
199 internal INVOCATION_FLAGS InvocationFlags
201 [System.Security.SecuritySafeCritical]
204 if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
206 INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
208 Type declaringType = DeclaringType;
211 // first take care of all the NO_INVOKE cases.
212 if (ContainsGenericParameters ||
213 ReturnType.IsByRef ||
214 (declaringType != null && declaringType.ContainsGenericParameters) ||
215 ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
216 ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
218 // We don't need other flags if this method cannot be invoked
219 invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
223 // this should be an invocable method, determine the other flags that participate in invocation
224 invocationFlags = RuntimeMethodHandle.GetSecurityFlags(this);
226 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0)
228 if ( (Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
229 (declaringType != null && declaringType.NeedsReflectionSecurityCheck) )
231 // If method is non-public, or declaring type is not visible
232 invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
234 else if (IsGenericMethod)
236 Type[] genericArguments = GetGenericArguments();
238 for (int i = 0; i < genericArguments.Length; i++)
240 if (genericArguments[i].NeedsReflectionSecurityCheck)
242 invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
251 if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
252 invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
253 #endif // FEATURE_APPX
255 m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
258 return m_invocationFlags;
264 [System.Security.SecurityCritical] // auto-generated
265 internal RuntimeMethodInfo(
266 RuntimeMethodHandleInternal handle, RuntimeType declaringType,
267 RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive)
269 Contract.Ensures(!m_handle.IsNull());
271 Contract.Assert(!handle.IsNullHandle());
272 Contract.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
274 m_bindingFlags = bindingFlags;
275 m_declaringType = declaringType;
276 m_keepalive = keepalive;
277 m_handle = handle.Value;
278 m_reflectedTypeCache = reflectedTypeCache;
279 m_methodAttributes = methodAttributes;
284 #region Legacy Remoting Cache
285 // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
286 // This member is currently being used by Remoting for caching remoting data. If you
287 // need to cache data here, talk to the Remoting team to work out a mechanism, so that
288 // both caching systems can happily work together.
289 private RemotingMethodCachedData m_cachedData;
291 internal RemotingMethodCachedData RemotingCache
295 // This grabs an internal copy of m_cachedData and uses
296 // that instead of looking at m_cachedData directly because
297 // the cache may get cleared asynchronously. This prevents
298 // us from having to take a lock.
299 RemotingMethodCachedData cache = m_cachedData;
302 cache = new RemotingMethodCachedData(this);
303 RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
311 #endif //FEATURE_REMOTING
313 #region Private Methods
314 RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
316 [System.Security.SecuritySafeCritical]
319 return new RuntimeMethodHandleInternal(m_handle);
323 private RuntimeType ReflectedTypeInternal
327 return m_reflectedTypeCache.GetRuntimeType();
331 [System.Security.SecurityCritical] // auto-generated
332 private ParameterInfo[] FetchNonReturnParameters()
334 if (m_parameters == null)
335 m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
340 [System.Security.SecurityCritical] // auto-generated
341 private ParameterInfo FetchReturnParameter()
343 if (m_returnParameter == null)
344 m_returnParameter = RuntimeParameterInfo.GetReturnParameter(this, this, Signature);
346 return m_returnParameter;
350 #region Internal Members
351 internal override string FormatNameAndSig(bool serialization)
353 // Serialization uses ToString to resolve MethodInfo overloads.
354 StringBuilder sbName = new StringBuilder(Name);
356 // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads.
357 // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString().
358 TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic;
361 sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format));
364 sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
367 return sbName.ToString();
370 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
371 internal override bool CacheEquals(object o)
373 RuntimeMethodInfo m = o as RuntimeMethodInfo;
375 if ((object)m == null)
378 return m.m_handle == m_handle;
381 internal Signature Signature
385 if (m_signature == null)
386 m_signature = new Signature(this, m_declaringType);
392 internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
394 // Differs from MethodHandle in that it will return a valid handle even for reflection only loaded types
395 internal RuntimeMethodHandle GetMethodHandle()
397 return new RuntimeMethodHandle(this);
400 [System.Security.SecuritySafeCritical] // auto-generated
401 internal RuntimeMethodInfo GetParentDefinition()
403 if (!IsVirtual || m_declaringType.IsInterface)
406 RuntimeType parent = (RuntimeType)m_declaringType.BaseType;
411 int slot = RuntimeMethodHandle.GetSlot(this);
413 if (RuntimeTypeHandle.GetNumVirtuals(parent) <= slot)
416 return (RuntimeMethodInfo)RuntimeType.GetMethodBase(parent, RuntimeTypeHandle.GetMethodAt(parent, slot));
419 // Unlike DeclaringType, this will return a valid type even for global methods
420 internal RuntimeType GetDeclaringTypeInternal()
422 return m_declaringType;
427 #region Object Overrides
428 public override String ToString()
430 if (m_toString == null)
431 m_toString = ReturnType.FormatTypeName() + " " + FormatNameAndSig();
436 public override int GetHashCode()
438 // See RuntimeMethodInfo.Equals() below.
440 return ValueType.GetHashCodeOfPtr(m_handle);
442 return base.GetHashCode();
445 [System.Security.SecuritySafeCritical] // auto-generated
446 public override bool Equals(object obj)
448 if (!IsGenericMethod)
449 return obj == (object)this;
451 // We cannot do simple object identity comparisons for generic methods.
452 // Equals will be called in CerHashTable when RuntimeType+RuntimeTypeCache.GetGenericMethodInfo()
453 // retrive items from and insert items into s_methodInstantiations which is a CerHashtable.
456 RuntimeMethodInfo mi = obj as RuntimeMethodInfo;
458 if (mi == null || !mi.IsGenericMethod)
461 // now we know that both operands are generic methods
463 IRuntimeMethodInfo handle1 = RuntimeMethodHandle.StripMethodInstantiation(this);
464 IRuntimeMethodInfo handle2 = RuntimeMethodHandle.StripMethodInstantiation(mi);
465 if (handle1.Value.Value != handle2.Value.Value)
468 Type[] lhs = GetGenericArguments();
469 Type[] rhs = mi.GetGenericArguments();
471 if (lhs.Length != rhs.Length)
474 for (int i = 0; i < lhs.Length; i++)
476 if (lhs[i] != rhs[i])
480 if (DeclaringType != mi.DeclaringType)
483 if (ReflectedType != mi.ReflectedType)
490 #region ICustomAttributeProvider
491 [System.Security.SecuritySafeCritical] // auto-generated
492 public override Object[] GetCustomAttributes(bool inherit)
494 return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit);
497 [System.Security.SecuritySafeCritical] // auto-generated
498 public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
500 if (attributeType == null)
501 throw new ArgumentNullException("attributeType");
502 Contract.EndContractBlock();
504 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
506 if (attributeRuntimeType == null)
507 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
509 return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
512 public override bool IsDefined(Type attributeType, bool inherit)
514 if (attributeType == null)
515 throw new ArgumentNullException("attributeType");
516 Contract.EndContractBlock();
518 RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
520 if (attributeRuntimeType == null)
521 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
523 return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
526 public override IList<CustomAttributeData> GetCustomAttributesData()
528 return CustomAttributeData.GetCustomAttributesInternal(this);
532 #region MemberInfo Overrides
533 public override String Name
535 [System.Security.SecuritySafeCritical] // auto-generated
539 m_name = RuntimeMethodHandle.GetName(this);
545 public override Type DeclaringType
549 if (m_reflectedTypeCache.IsGlobal)
552 return m_declaringType;
556 public override Type ReflectedType
560 if (m_reflectedTypeCache.IsGlobal)
563 return m_reflectedTypeCache.GetRuntimeType();
567 public override MemberTypes MemberType { get { return MemberTypes.Method; } }
568 public override int MetadataToken
570 [System.Security.SecuritySafeCritical] // auto-generated
571 get { return RuntimeMethodHandle.GetMethodDef(this); }
573 public override Module Module { get { return GetRuntimeModule(); } }
574 internal RuntimeType GetRuntimeType() { return m_declaringType; }
575 internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
576 internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
578 public override bool IsSecurityCritical
580 get { return RuntimeMethodHandle.IsSecurityCritical(this); }
582 public override bool IsSecuritySafeCritical
584 get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); }
586 public override bool IsSecurityTransparent
588 get { return RuntimeMethodHandle.IsSecurityTransparent(this); }
592 #region MethodBase Overrides
593 [System.Security.SecuritySafeCritical] // auto-generated
594 internal override ParameterInfo[] GetParametersNoCopy()
596 FetchNonReturnParameters();
601 [System.Security.SecuritySafeCritical] // auto-generated
602 [System.Diagnostics.Contracts.Pure]
603 public override ParameterInfo[] GetParameters()
605 FetchNonReturnParameters();
607 if (m_parameters.Length == 0)
610 ParameterInfo[] ret = new ParameterInfo[m_parameters.Length];
612 Array.Copy(m_parameters, ret, m_parameters.Length);
617 public override MethodImplAttributes GetMethodImplementationFlags()
619 return RuntimeMethodHandle.GetImplAttributes(this);
622 internal bool IsOverloaded
626 return m_reflectedTypeCache.GetMethodList(MemberListType.CaseSensitive, Name).Length > 1;
630 public override RuntimeMethodHandle MethodHandle
634 Type declaringType = DeclaringType;
635 if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
636 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
637 return new RuntimeMethodHandle(this);
641 public override MethodAttributes Attributes { get { return m_methodAttributes; } }
643 public override CallingConventions CallingConvention
647 return Signature.CallingConvention;
651 [System.Security.SecuritySafeCritical] // overrides SafeCritical member
653 #pragma warning disable 618
654 [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)]
655 #pragma warning restore 618
657 public override MethodBody GetMethodBody()
659 MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
661 mb.m_methodBase = this;
666 #region Invocation Logic(On MemberBase)
667 private void CheckConsistency(Object target)
669 // only test instance methods
670 if ((m_methodAttributes & MethodAttributes.Static) != MethodAttributes.Static)
672 if (!m_declaringType.IsInstanceOfType(target))
675 throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg"));
677 throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch"));
682 [System.Security.SecuritySafeCritical]
683 private void ThrowNoInvokeException()
685 // method is ReflectionOnly
686 Type declaringType = DeclaringType;
687 if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
689 throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
691 // method is on a class that contains stack pointers
692 else if ((InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS) != 0)
694 throw new NotSupportedException();
697 else if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
699 throw new NotSupportedException();
701 // method is generic or on a generic class
702 else if (DeclaringType.ContainsGenericParameters || ContainsGenericParameters)
704 throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenParam"));
706 // method is abstract class
709 throw new MemberAccessException();
711 // ByRef return are not allowed in reflection
712 else if (ReturnType.IsByRef)
714 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ByRefReturn"));
717 throw new TargetException();
720 [System.Security.SecuritySafeCritical]
721 [DebuggerStepThroughAttribute]
722 [Diagnostics.DebuggerHidden]
723 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
724 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
726 object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
728 #region Security Check
729 INVOCATION_FLAGS invocationFlags = InvocationFlags;
732 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
734 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
735 RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
736 if (caller != null && !caller.IsSafeForReflection())
737 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
741 if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
744 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0)
745 CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess);
747 if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
748 #endif // !FEATURE_CORECLR
749 RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags);
753 return UnsafeInvokeInternal(obj, parameters, arguments);
756 [System.Security.SecurityCritical]
757 [DebuggerStepThroughAttribute]
758 [Diagnostics.DebuggerHidden]
759 internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
761 object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
763 return UnsafeInvokeInternal(obj, parameters, arguments);
766 [System.Security.SecurityCritical]
767 [DebuggerStepThroughAttribute]
768 [Diagnostics.DebuggerHidden]
769 private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
771 if (arguments == null || arguments.Length == 0)
772 return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
775 Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
777 // copy out. This should be made only if ByRef are present.
778 for (int index = 0; index < arguments.Length; index++)
779 parameters[index] = arguments[index];
785 [DebuggerStepThroughAttribute]
786 [Diagnostics.DebuggerHidden]
787 private object[] InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
789 Signature sig = Signature;
792 int formalCount = sig.Arguments.Length;
793 int actualCount = (parameters != null) ? parameters.Length : 0;
795 INVOCATION_FLAGS invocationFlags = InvocationFlags;
797 // INVOCATION_FLAGS_CONTAINS_STACK_POINTERS means that the struct (either the declaring type or the return type)
798 // contains pointers that point to the stack. This is either a ByRef or a TypedReference. These structs cannot
799 // be boxed and thus cannot be invoked through reflection which only deals with boxed value type objects.
800 if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS)) != 0)
801 ThrowNoInvokeException();
803 // check basic method consistency. This call will throw if there are problems in the target/method relationship
804 CheckConsistency(obj);
806 if (formalCount != actualCount)
807 throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
809 if (actualCount != 0)
810 return CheckArguments(parameters, binder, invokeAttr, culture, sig);
817 #region MethodInfo Overrides
818 public override Type ReturnType
820 get { return Signature.ReturnType; }
823 public override ICustomAttributeProvider ReturnTypeCustomAttributes
825 get { return ReturnParameter; }
828 public override ParameterInfo ReturnParameter
830 [System.Security.SecuritySafeCritical] // auto-generated
833 Contract.Ensures(m_returnParameter != null);
835 FetchReturnParameter();
836 return m_returnParameter as ParameterInfo;
840 [System.Security.SecuritySafeCritical] // auto-generated
841 public override MethodInfo GetBaseDefinition()
843 if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface)
846 int slot = RuntimeMethodHandle.GetSlot(this);
847 RuntimeType declaringType = (RuntimeType)DeclaringType;
848 RuntimeType baseDeclaringType = declaringType;
849 RuntimeMethodHandleInternal baseMethodHandle = new RuntimeMethodHandleInternal();
852 int cVtblSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
854 if (cVtblSlots <= slot)
857 baseMethodHandle = RuntimeTypeHandle.GetMethodAt(declaringType, slot);
858 baseDeclaringType = declaringType;
860 declaringType = (RuntimeType)declaringType.BaseType;
861 } while (declaringType != null);
863 return(MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle);
866 [System.Security.SecuritySafeCritical]
867 public override Delegate CreateDelegate(Type delegateType)
869 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
871 // This API existed in v1/v1.1 and only expected to create closed
872 // instance delegates. Constrain the call to BindToMethodInfo to
873 // open delegates only for backwards compatibility. But we'll allow
874 // relaxed signature checking and open static delegates because
875 // there's no ambiguity there (the caller would have to explicitly
876 // pass us a static method or a method with a non-exact signature
877 // and the only change in behavior from v1.1 there is that we won't
879 return CreateDelegateInternal(
882 DelegateBindingFlags.OpenDelegateOnly | DelegateBindingFlags.RelaxedSignature,
886 [System.Security.SecuritySafeCritical]
887 public override Delegate CreateDelegate(Type delegateType, Object target)
889 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
891 // This API is new in Whidbey and allows the full range of delegate
892 // flexability (open or closed delegates binding to static or
893 // instance methods with relaxed signature checking). The delegate
894 // can also be closed over null. There's no ambiguity with all these
895 // options since the caller is providing us a specific MethodInfo.
896 return CreateDelegateInternal(
899 DelegateBindingFlags.RelaxedSignature,
903 [System.Security.SecurityCritical]
904 private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark)
906 // Validate the parameters.
907 if (delegateType == null)
908 throw new ArgumentNullException("delegateType");
909 Contract.EndContractBlock();
911 RuntimeType rtType = delegateType as RuntimeType;
913 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "delegateType");
915 if (!rtType.IsDelegate())
916 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "delegateType");
918 Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark);
921 throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
930 [System.Security.SecuritySafeCritical] // auto-generated
931 public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation)
933 if (methodInstantiation == null)
934 throw new ArgumentNullException("methodInstantiation");
935 Contract.EndContractBlock();
937 RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length];
939 if (!IsGenericMethodDefinition)
940 throw new InvalidOperationException(
941 Environment.GetResourceString("Arg_NotGenericMethodDefinition", this));
943 for (int i = 0; i < methodInstantiation.Length; i++)
945 Type methodInstantiationElem = methodInstantiation[i];
947 if (methodInstantiationElem == null)
948 throw new ArgumentNullException();
950 RuntimeType rtMethodInstantiationElem = methodInstantiationElem as RuntimeType;
952 if (rtMethodInstantiationElem == null)
954 Type[] methodInstantiationCopy = new Type[methodInstantiation.Length];
955 for (int iCopy = 0; iCopy < methodInstantiation.Length; iCopy++)
956 methodInstantiationCopy[iCopy] = methodInstantiation[iCopy];
957 methodInstantiation = methodInstantiationCopy;
958 return System.Reflection.Emit.MethodBuilderInstantiation.MakeGenericMethod(this, methodInstantiation);
961 methodInstantionRuntimeType[i] = rtMethodInstantiationElem;
964 RuntimeType[] genericParameters = GetGenericArgumentsInternal();
966 RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters);
968 MethodInfo ret = null;
972 ret = RuntimeType.GetMethodBase(ReflectedTypeInternal,
973 RuntimeMethodHandle.GetStubIfNeeded(new RuntimeMethodHandleInternal(this.m_handle), m_declaringType, methodInstantionRuntimeType)) as MethodInfo;
975 catch (VerificationException e)
977 RuntimeType.ValidateGenericArguments(this, methodInstantionRuntimeType, e);
984 internal RuntimeType[] GetGenericArgumentsInternal()
986 return RuntimeMethodHandle.GetMethodInstantiationInternal(this);
989 public override Type[] GetGenericArguments()
991 Type[] types = RuntimeMethodHandle.GetMethodInstantiationPublic(this);
995 types = EmptyArray<Type>.Value;
1000 public override MethodInfo GetGenericMethodDefinition()
1002 if (!IsGenericMethod)
1003 throw new InvalidOperationException();
1004 Contract.EndContractBlock();
1006 return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo;
1009 public override bool IsGenericMethod
1011 get { return RuntimeMethodHandle.HasMethodInstantiation(this); }
1014 public override bool IsGenericMethodDefinition
1016 get { return RuntimeMethodHandle.IsGenericMethodDefinition(this); }
1019 public override bool ContainsGenericParameters
1023 if (DeclaringType != null && DeclaringType.ContainsGenericParameters)
1026 if (!IsGenericMethod)
1029 Type[] pis = GetGenericArguments();
1030 for (int i = 0; i < pis.Length; i++)
1032 if (pis[i].ContainsGenericParameters)
1041 #region ISerializable Implementation
1042 [System.Security.SecurityCritical] // auto-generated
1043 public void GetObjectData(SerializationInfo info, StreamingContext context)
1046 throw new ArgumentNullException("info");
1047 Contract.EndContractBlock();
1049 if (m_reflectedTypeCache.IsGlobal)
1050 throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
1052 MemberInfoSerializationHolder.GetSerializationInfo(
1055 ReflectedTypeInternal,
1057 SerializationToString(),
1059 IsGenericMethod & !IsGenericMethodDefinition ? GetGenericArguments() : null);
1062 internal string SerializationToString()
1064 return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
1068 #region Legacy Internal
1069 internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark)
1071 IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark);
1076 return RuntimeType.GetMethodBase(method);