【问题标题】:Using System.Reflection to Get a Method's Full Name使用 System.Reflection 获取方法的全名
【发布时间】:2011-02-27 10:36:43
【问题描述】:

我有一个如下所示的类:

public class MyClass
{

...

    protected void MyMethod()
    {
    ...
    string myName = System.Reflection.MethodBase.GetCurrentMethod.Name;
    ...
    }

...

}

myName 的值为“MyMethod”。

有没有一种方法可以让我使用反射来获取 myName 的“MyClass.MyMethod”值?

【问题讨论】:

标签: c# .net reflection


【解决方案1】:

您可以查看从GetCurrentMethod 获得的MethodBase 中的ReflectedType,即,

MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
string methodName = method.Name;
string className = method.ReflectedType.Name;

string fullMethodName = className + "." + methodName;

【讨论】:

  • 正是我想要的。谢谢!
  • 请注意,“ReflectedType”并未像预期的那样考虑运行时多态性。
  • 在异步函数中,名称作为 MoveNext 返回。解决异步函数中名称的唯一答案是stackoverflow.com/questions/2968352/…
【解决方案2】:

并获取带参数的完整方法名称:

var method = System.Reflection.MethodBase.GetCurrentMethod();
var fullName = string.Format("{0}.{1}({2})", method.ReflectedType.FullName, method.Name, string.Join(",", method.GetParameters().Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)).ToArray()));

【讨论】:

  • +1 绝对是最有用的解决方案。当您的代码库在不同的命名空间中有重复的类名时,包括 FullName 有助于查明类。并且包含参数有助于区分重载方法。
【解决方案3】:

我认为现在最好这样做:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}";

【讨论】:

  • 一直在寻找这个,以便我可以记录合格的名称,这就是我最终采用的方法。只是因为它小巧、简单并且可以满足我的需求。
【解决方案4】:

扩展Ruben's,可以得到这样的全名:

var info = System.Reflection.MethodBase.GetCurrentMethod();
var result = string.Format(
                 "{0}.{1}.{2}()",
                 info.ReflectedType.Namespace,
                 info.ReflectedType.Name,
                 info.Name);

您可以将其添加到接收 MethodBase 参数并生成字符串的静态方法中。

【讨论】:

    【解决方案5】:

    你可以像这样得到全名:

    var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;
    

    【讨论】:

      【解决方案6】:

      在 C# 6 中,您可以使用 nameof

      string myName = nameof(MyMethod);
      

      【讨论】:

      • 是的,但它只返回名称,而不是全名。在给出的示例中,它返回字符串"MyMethod",而不是"MyClass.MyMethod"
      【解决方案7】:

      感谢上面的帖子,他们帮助我为 MVC 4 HTMLHelpers 创建了一个强大的类型绑定系统,如下所示。

       public static MvcHtmlString StrongTypeBinder(this HtmlHelper htmlhelper, Expression<Func<object, string>> SomeLambda)
          {
              var body = SomeLambda.Body;
              var propertyName = ((PropertyInfo)((MemberExpression)body).Member).Name;
              HtmlString = @"
                  <input type='text' name='@Id' id='@Id'/>
                  ";
              HtmlString = HtmlString.Replace("@Id", propertyName);
              var finalstring = new MvcHtmlString(HtmlString);
              return finalstring;
      
          }
      

      在任何 CSHTML 视图中使用上述代码:

      @Html.StrongTypeBinder(p=>Model.SelectedDate)
      

      这允许我将 ViewModel 中的任何属性绑定到我想要的任何 HTML 元素类型。在上面的示例中,我绑定了用户选择后发回的所选数据的名称字段。 post back 后的 viewmodel 会自动显示选中的值。

      【讨论】:

        【解决方案8】:

        在异步方法中运行时会遇到问题。解决方法如下:

        如果您需要完全限定类名,则必须使用 DeclaringType.FullName 而不是 DeclaringType.Name

        此代码不适用于匿名或 lambda 方法。

        using System.Runtime.CompilerServices;
        
        static string GetMethodContextName() {
            var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName();
            return name;
        }
        
        static string GetMethodContextName(this MethodBase method) {
            if (method.DeclaringType.GetInterfaces().Any(i => i == typeof(IAsyncStateMachine))) {
                var generatedType = method.DeclaringType;
                var originalType = generatedType.DeclaringType;
                var foundMethod = originalType.GetMethods(
                      BindingFlags.Instance | BindingFlags.Static 
                    | BindingFlags.Public | BindingFlags.NonPublic 
                    | BindingFlags.DeclaredOnly)
                    .Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType);
                return foundMethod.DeclaringType.Name + "." + foundMethod.Name;
            } else {
                return method.DeclaringType.Name + "." + method.Name;
            }
        }
        

        这是一个示例用法:

        class Program { 
            static void Main(string[] args) {
                // outputs Program.Main
                Console.WriteLine(GetMethodContextName());
            }
        }
        

        【讨论】:

        • 考虑使用更具体的名称 - GetCurrentMethodFullName() 和 GetMethodFullName(此 MethodBase 方法)
        • 请注意,Resharper 会警告 method.DeclaringType 可以为 null
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-14
        • 1970-01-01
        • 2016-03-11
        • 2013-12-24
        • 1970-01-01
        相关资源
        最近更新 更多