MethodBase.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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.
  4. using System.Globalization;
  5. using System.Diagnostics;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. namespace System.Reflection
  9. {
  10. public abstract partial class MethodBase : MemberInfo
  11. {
  12. protected MethodBase() { }
  13. public abstract ParameterInfo[] GetParameters();
  14. public abstract MethodAttributes Attributes { get; }
  15. public virtual MethodImplAttributes MethodImplementationFlags => GetMethodImplementationFlags();
  16. public abstract MethodImplAttributes GetMethodImplementationFlags();
  17. public virtual MethodBody? GetMethodBody() { throw new InvalidOperationException(); }
  18. public virtual CallingConventions CallingConvention => CallingConventions.Standard;
  19. public bool IsAbstract => (Attributes & MethodAttributes.Abstract) != 0;
  20. public bool IsConstructor =>
  21. // To be backward compatible we only return true for instance RTSpecialName ctors.
  22. this is ConstructorInfo &&
  23. !IsStatic &&
  24. (Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName;
  25. public bool IsFinal => (Attributes & MethodAttributes.Final) != 0;
  26. public bool IsHideBySig => (Attributes & MethodAttributes.HideBySig) != 0;
  27. public bool IsSpecialName => (Attributes & MethodAttributes.SpecialName) != 0;
  28. public bool IsStatic => (Attributes & MethodAttributes.Static) != 0;
  29. public bool IsVirtual => (Attributes & MethodAttributes.Virtual) != 0;
  30. public bool IsAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
  31. public bool IsFamily => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
  32. public bool IsFamilyAndAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
  33. public bool IsFamilyOrAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
  34. public bool IsPrivate => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
  35. public bool IsPublic => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
  36. public virtual bool IsConstructedGenericMethod => IsGenericMethod && !IsGenericMethodDefinition;
  37. public virtual bool IsGenericMethod => false;
  38. public virtual bool IsGenericMethodDefinition => false;
  39. public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
  40. public virtual bool ContainsGenericParameters => false;
  41. [DebuggerHidden]
  42. [DebuggerStepThrough]
  43. public object? Invoke(object? obj, object?[]? parameters) => Invoke(obj, BindingFlags.Default, binder: null, parameters: parameters, culture: null);
  44. public abstract object? Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture);
  45. public abstract RuntimeMethodHandle MethodHandle { get; }
  46. public virtual bool IsSecurityCritical => throw NotImplemented.ByDesign;
  47. public virtual bool IsSecuritySafeCritical => throw NotImplemented.ByDesign;
  48. public virtual bool IsSecurityTransparent => throw NotImplemented.ByDesign;
  49. public override bool Equals(object? obj) => base.Equals(obj);
  50. public override int GetHashCode() => base.GetHashCode();
  51. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  52. public static bool operator ==(MethodBase? left, MethodBase? right)
  53. {
  54. // Test "right" first to allow branch elimination when inlined for null checks (== null)
  55. // so it can become a simple test
  56. if (right is null)
  57. {
  58. // return true/false not the test result https://github.com/dotnet/coreclr/issues/914
  59. return (left is null) ? true : false;
  60. }
  61. // Try fast reference equality and opposite null check prior to calling the slower virtual Equals
  62. if ((object?)left == (object)right)
  63. {
  64. return true;
  65. }
  66. return (left is null) ? false : left.Equals(right);
  67. }
  68. public static bool operator !=(MethodBase? left, MethodBase? right) => !(left == right);
  69. internal const int MethodNameBufferSize = 100;
  70. internal static void AppendParameters(ref ValueStringBuilder sbParamList, Type[] parameterTypes, CallingConventions callingConvention)
  71. {
  72. string comma = "";
  73. for (int i = 0; i < parameterTypes.Length; i++)
  74. {
  75. Type t = parameterTypes[i];
  76. sbParamList.Append(comma);
  77. string typeName = t.FormatTypeName();
  78. // Legacy: Why use "ByRef" for by ref parameters? What language is this?
  79. // VB uses "ByRef" but it should precede (not follow) the parameter name.
  80. // Why don't we just use "&"?
  81. if (t.IsByRef)
  82. {
  83. sbParamList.Append(typeName.AsSpan().TrimEnd('&'));
  84. sbParamList.Append(" ByRef");
  85. }
  86. else
  87. {
  88. sbParamList.Append(typeName);
  89. }
  90. comma = ", ";
  91. }
  92. if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
  93. {
  94. sbParamList.Append(comma);
  95. sbParamList.Append("...");
  96. }
  97. }
  98. }
  99. }