将C#方法名称转换为文本

时间:2015-11-10 17:17:38

标签: c#

我在Visual Studio 2013中使用通用处理程序。

我要做的是创建一个包含方法名称的URL,但是我希望方法的名称是真正的代码,这样它就不会被硬编码并且如果函数名称那么跟随被改变了。

如果我在C或C ++中这样做,我会说:

#define GENERATE_REFERENCE(text) #text

我真的不在乎它是作为一个方法调用形成的,因为我在这里有原型

我在尝试做的C#中的“伪代码”:

public class MyClass {
    public void SayHello (String name)
    {
    ...
    }

    public void GenerateLink()
    {
         url = "... "+GenerateReference(this.SayHello);
         // url would be "... SayHello";

    }
    public String GenerateReference( DataType method )
    {
         // Is there some way to do this?
         return method.MethodName.ToString();
    }
}

我的问题与建议的重复问题get methodinfo from a method reference C#不同,因为我的问题来自一个对C#机制(新手)非常无知的地方。可疑的重复问题意味着更高层次的理解,远远超出我在我的问题中所表明的理解 - 我不太了解这个问题。我从来没有从我的搜索中找到这个答案。

6 个答案:

答案 0 :(得分:9)

c#6引入了一个名为nameof的新运算符,它使用方法名称删除了这些硬编码字符串。

您可以按如下方式使用它:nameof(Class.Method)

答案 1 :(得分:9)

C#6

nameof(MyClass.SayHello)

在C#6之前

public static String GenerateReference<T>(Expression<Action<T>> expression)
{
    var member = expression.Body as MethodCallExpression;

    if (member != null)
        return member.Method.Name;

    throw new ArgumentException("Expression is not a method", "expression");
}

GenerateReference<MyClass>(c => c.SayHello(null));

信用转到https://stackoverflow.com/a/9382501/471321

答案 2 :(得分:3)

这可能是您用例的最简单方法;

Action<string> del = this.SayHello;
string ret = del.Method.Name;

答案 3 :(得分:2)

C#6.0包括nameof功能。 但是,默认情况下,不知道您在VS2013和C#6.0中是否已启用;我建议使用System.Reflection

我会用这样的东西。

System.Reflection.MethodBase.GetCurrentMethod().Name

并根据需要将方法名称作为参数传递。

干杯!

答案 4 :(得分:2)

您可以在参数上使用CallerMemberNameAttribute,以便让编译器在早期版本的C#中为您插入名称。

这是一个依赖重载来获得正确答案的示例。请注意,如果你的真实&#34;方法都有自己独特的参数,你不需要虚拟重载,可以完全避免QueryMethodNameHelper参数

// This class is used both as a dummy parameter for overload resolution
// and to hold the GetMyName method. You can call it whatever you want
class QueryMethodNameHelper
{
  private QueryMethodNameHelper() { }

  public static readonly QueryMethodNameHelper Instance = 
    new QueryMethodNameHelper();

  public static string GetMyName([CallerMemberName] string 
    name = "[unknown]")
  {
    return name;
  }
}

class Program
{
  // The real method
  static void SayHello()
  {
    Console.WriteLine("Hello!");
  }

  // The dummy method; the parameter is never used, but it ensures
  // we can have an overload that returns the string name
  static string SayHello(QueryMethodNameHelper dummy)
  {
    return QueryMethodNameHelper.GetMyName();
  }

  // Second real method that has an argument
  static void DoStuff(int value)
  {
    Console.WriteLine("Doing stuff... " + value);
  }

  // Dummy method can use default parameter because
  // there is no ambiguity
  static string DoStuff(QueryMethodNameHelper dummy = null)
  {
    return QueryMethodNameHelper.GetMyName();
  }

  static void Main(string[] args)
  {
    string s = SayHello(QueryMethodNameHelper.Instance);
    Console.WriteLine(s);
    SayHello();

    string s2 = DoStuff();
    Console.WriteLine(s2);
    DoStuff(42);
  }
}

此示例具有在编译时注入字符串的好处(查找元数据没有运行时开销),但它确实要求您保持方法名称同步(例如,如果您重命名&#34; real& #34; SayHello您还需要重命名帮助器SayHello)。幸运的是,如果你单击&#34;重命名重载&#34;重写器对话框将为你做这件事。复选框,但默认情况下不启用。

答案 5 :(得分:0)

使用System.Reflection(在C#6.0之前):

typeof(MyClass).GetMethod("SayHello").Name

或C#6.0及更高版本的名称:

nameof(SayHello)