3 // Copyright(c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
9 namespace System.Reflection
12 using System.Diagnostics;
13 using System.Globalization;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
16 using System.Security.Permissions;
18 using System.Threading;
21 // Invocation cached flags. Those are used in unmanaged code as well
22 // so be careful if you change them
25 internal enum INVOCATION_FLAGS : uint
27 INVOCATION_FLAGS_UNKNOWN = 0x00000000,
28 INVOCATION_FLAGS_INITIALIZED = 0x00000001,
29 // it's used for both method and field to signify that no access is allowed
30 INVOCATION_FLAGS_NO_INVOKE = 0x00000002,
31 INVOCATION_FLAGS_NEED_SECURITY = 0x00000004,
32 // Set for static ctors and ctors on abstract types, which
33 // can be invoked only if the "this" object is provided (even if it's null).
34 INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008,
35 // because field and method are different we can reuse the same bits
37 INVOCATION_FLAGS_IS_CTOR = 0x00000010,
38 INVOCATION_FLAGS_RISKY_METHOD = 0x00000020,
39 INVOCATION_FLAGS_NON_W8P_FX_API = 0x00000040,
40 INVOCATION_FLAGS_IS_DELEGATE_CTOR = 0x00000080,
41 INVOCATION_FLAGS_CONTAINS_STACK_POINTERS = 0x00000100,
43 INVOCATION_FLAGS_SPECIAL_FIELD = 0x00000010,
44 INVOCATION_FLAGS_FIELD_SPECIAL_CAST = 0x00000020,
46 // temporary flag used for flagging invocation of method vs ctor
47 // this flag never appears on the instance m_invocationFlag and is simply
48 // passed down from within ConstructorInfo.Invoke()
49 INVOCATION_FLAGS_CONSTRUCTOR_INVOKE = 0x10000000,
53 [ClassInterface(ClassInterfaceType.None)]
54 [ComDefaultInterface(typeof(_MethodBase))]
55 #pragma warning disable 618
56 [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
57 #pragma warning restore 618
58 [System.Runtime.InteropServices.ComVisible(true)]
59 public abstract partial class MethodBase : MemberInfo, _MethodBase
61 #region Static Members
62 public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle)
64 if (handle.IsNullHandle())
65 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
68 MethodBase m = GetMethodFromHandleInternalType (handle.Value, IntPtr.Zero);
70 throw new ArgumentException ("The handle is invalid.");
72 MethodBase m = RuntimeType.GetMethodBase(handle.GetMethodInfo());
75 Type declaringType = m.DeclaringType;
76 if (declaringType != null && declaringType.IsGenericType)
77 throw new ArgumentException(String.Format(
78 CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGeneric"),
79 m, declaringType.GetGenericTypeDefinition()));
84 [System.Runtime.InteropServices.ComVisible(false)]
85 public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
87 if (handle.IsNullHandle())
88 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
91 MethodBase m = GetMethodFromHandleInternalType (handle.Value, declaringType.Value);
93 throw new ArgumentException ("The handle is invalid.");
96 return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo());
101 [MethodImplAttribute (MethodImplOptions.InternalCall)]
102 public extern static MethodBase GetCurrentMethod ();
104 [System.Security.DynamicSecurityMethod] // Specify DynamicSecurityMethod attribute to prevent inlining of the caller.
105 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
106 public static MethodBase GetCurrentMethod()
108 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
109 return RuntimeMethodInfo.InternalGetCurrentMethod(ref stackMark);
115 protected MethodBase() { }
119 public static bool operator ==(MethodBase left, MethodBase right)
121 if (ReferenceEquals(left, right))
124 if ((object)left == null || (object)right == null)
127 MethodInfo method1, method2;
128 ConstructorInfo constructor1, constructor2;
130 if ((method1 = left as MethodInfo) != null && (method2 = right as MethodInfo) != null)
131 return method1 == method2;
132 else if ((constructor1 = left as ConstructorInfo) != null && (constructor2 = right as ConstructorInfo) != null)
133 return constructor1 == constructor2;
138 public static bool operator !=(MethodBase left, MethodBase right)
140 return !(left == right);
142 #endif // !FEATURE_CORECLR
144 public override bool Equals(object obj)
146 return base.Equals(obj);
149 public override int GetHashCode()
151 return base.GetHashCode();
154 #region Internal Members
156 [System.Security.SecurityCritical]
157 private IntPtr GetMethodDesc() { return MethodHandle.Value; }
161 // The C# dynamic and VB late bound binders need to call this API. Since we don't have time to make this
162 // public in Dev11, the C# and VB binders currently call this through a delegate.
163 // When we make this API public (hopefully) in Dev12 we need to change the C# and VB binders to call this
164 // probably statically. The code is located in:
165 // C#: ndp\fx\src\CSharp\Microsoft\CSharp\SymbolTable.cs - Microsoft.CSharp.RuntimeBinder.SymbolTable..cctor
166 // VB: vb\runtime\msvbalib\helpers\Symbols.vb - Microsoft.VisualBasic.CompilerServices.Symbols..cctor
167 internal virtual bool IsDynamicallyInvokable
177 #region Public Abstract\Virtual Members
178 internal virtual ParameterInfo[] GetParametersNoCopy() { return GetParameters (); }
180 [System.Diagnostics.Contracts.Pure]
181 public abstract ParameterInfo[] GetParameters();
183 public virtual MethodImplAttributes MethodImplementationFlags
187 return GetMethodImplementationFlags();
191 public abstract MethodImplAttributes GetMethodImplementationFlags();
193 public abstract RuntimeMethodHandle MethodHandle { get; }
195 public abstract MethodAttributes Attributes { get; }
197 public abstract Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
199 public virtual CallingConventions CallingConvention { get { return CallingConventions.Standard; } }
201 [System.Runtime.InteropServices.ComVisible(true)]
202 public virtual Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
204 public virtual bool IsGenericMethodDefinition { get { return false; } }
206 public virtual bool ContainsGenericParameters { get { return false; } }
208 public virtual bool IsGenericMethod { get { return false; } }
210 public virtual bool IsSecurityCritical { get { throw new NotImplementedException(); } }
212 public virtual bool IsSecuritySafeCritical { get { throw new NotImplementedException(); } }
214 public virtual bool IsSecurityTransparent { get { throw new NotImplementedException(); } }
218 #region Public Members
219 [DebuggerStepThroughAttribute]
220 [Diagnostics.DebuggerHidden]
221 public Object Invoke(Object obj, Object[] parameters)
223 // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
224 // But to maintain backward compatibility we can't switch to calling an
225 // internal overload that takes a stack mark.
226 // Fortunately the stack walker skips all the reflection invocation frames including this one.
227 // So this method will never be returned by the stack walker as the caller.
228 // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
229 return Invoke(obj, BindingFlags.Default, null, parameters, null);
232 public bool IsPublic { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } }
234 public bool IsPrivate { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } }
236 public bool IsFamily { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } }
238 public bool IsAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } }
240 public bool IsFamilyAndAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } }
242 public bool IsFamilyOrAssembly { get {return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } }
244 public bool IsStatic { get { return(Attributes & MethodAttributes.Static) != 0; } }
246 public bool IsFinal { get { return(Attributes & MethodAttributes.Final) != 0; }
248 public bool IsVirtual { get { return(Attributes & MethodAttributes.Virtual) != 0; }
250 public bool IsHideBySig { get { return(Attributes & MethodAttributes.HideBySig) != 0; } }
252 public bool IsAbstract { get { return(Attributes & MethodAttributes.Abstract) != 0; } }
254 public bool IsSpecialName { get { return(Attributes & MethodAttributes.SpecialName) != 0; } }
256 [System.Runtime.InteropServices.ComVisible(true)]
257 public bool IsConstructor
261 // To be backward compatible we only return true for instance RTSpecialName ctors.
262 return (this is ConstructorInfo &&
264 ((Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName));
268 [System.Security.SecuritySafeCritical]
269 #pragma warning disable 618
270 [ReflectionPermissionAttribute(SecurityAction.Demand, Flags=ReflectionPermissionFlag.MemberAccess)]
271 #pragma warning restore 618
272 public virtual MethodBody GetMethodBody()
274 throw new InvalidOperationException();
278 #region Internal Methods
279 // helper method to construct the string representation of the parameter list
282 internal static string ConstructParameters(Type[] parameterTypes, CallingConventions callingConvention, bool serialization)
284 StringBuilder sbParamList = new StringBuilder();
287 for (int i = 0; i < parameterTypes.Length; i++)
289 Type t = parameterTypes[i];
291 sbParamList.Append(comma);
293 string typeName = t.FormatTypeName(serialization);
295 // Legacy: Why use "ByRef" for by ref parameters? What language is this?
296 // VB uses "ByRef" but it should precede (not follow) the parameter name.
297 // Why don't we just use "&"?
298 if (t.IsByRef && !serialization)
300 sbParamList.Append(typeName.TrimEnd(new char[] { '&' }));
301 sbParamList.Append(" ByRef");
305 sbParamList.Append(typeName);
311 if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
313 sbParamList.Append(comma);
314 sbParamList.Append("...");
317 return sbParamList.ToString();
320 internal string FullName
324 return String.Format("{0}.{1}", DeclaringType.FullName, FormatNameAndSig());
327 internal string FormatNameAndSig()
329 return FormatNameAndSig(false);
332 internal virtual string FormatNameAndSig(bool serialization)
334 // Serialization uses ToString to resolve MethodInfo overloads.
335 StringBuilder sbName = new StringBuilder(Name);
338 sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
341 return sbName.ToString();
344 internal virtual Type[] GetParameterTypes()
346 ParameterInfo[] paramInfo = GetParametersNoCopy();
348 Type[] parameterTypes = new Type[paramInfo.Length];
349 for (int i = 0; i < paramInfo.Length; i++)
350 parameterTypes[i] = paramInfo[i].ParameterType;
352 return parameterTypes;
355 [System.Security.SecuritySafeCritical]
356 internal Object[] CheckArguments(Object[] parameters, Binder binder,
357 BindingFlags invokeAttr, CultureInfo culture, Signature sig)
359 // copy the arguments in a different array so we detach from any user changes
360 Object[] copyOfParameters = new Object[parameters.Length];
362 ParameterInfo[] p = null;
363 for (int i = 0; i < parameters.Length; i++)
365 Object arg = parameters[i];
366 RuntimeType argRT = sig.Arguments[i];
368 if (arg == Type.Missing)
371 p = GetParametersNoCopy();
372 if (p[i].DefaultValue == System.DBNull.Value)
373 throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),"parameters");
374 arg = p[i].DefaultValue;
376 copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
379 return copyOfParameters;
384 #region _MethodBase Implementation
386 Type _MethodBase.GetType() { return base.GetType(); }
387 bool _MethodBase.IsPublic { get { return IsPublic; } }
388 bool _MethodBase.IsPrivate { get { return IsPrivate; } }
389 bool _MethodBase.IsFamily { get { return IsFamily; } }
390 bool _MethodBase.IsAssembly { get { return IsAssembly; } }
391 bool _MethodBase.IsFamilyAndAssembly { get { return IsFamilyAndAssembly; } }
392 bool _MethodBase.IsFamilyOrAssembly { get { return IsFamilyOrAssembly; } }
393 bool _MethodBase.IsStatic { get { return IsStatic; } }
394 bool _MethodBase.IsFinal { get { return IsFinal; } }
395 bool _MethodBase.IsVirtual { get { return IsVirtual; } }
396 bool _MethodBase.IsHideBySig { get { return IsHideBySig; } }
397 bool _MethodBase.IsAbstract { get { return IsAbstract; } }
398 bool _MethodBase.IsSpecialName { get { return IsSpecialName; } }
399 bool _MethodBase.IsConstructor { get { return IsConstructor; } }
401 void _MethodBase.GetTypeInfoCount(out uint pcTInfo)
403 throw new NotImplementedException();
406 void _MethodBase.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
408 throw new NotImplementedException();
411 void _MethodBase.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
413 throw new NotImplementedException();
416 // If you implement this method, make sure to include _MethodBase.Invoke in VM\DangerousAPIs.h and
417 // include _MethodBase in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
418 void _MethodBase.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
420 throw new NotImplementedException();