Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C#方法名称转换为文本_C# - Fatal编程技术网

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

将C#方法名称转换为文本,c#,C#,我正在Visual Studio 2013中使用通用处理程序 我想做的是创建一个包含方法名的URL,但我希望方法名是真实代码,这样它就不会被硬编码,如果函数名被更改,它也不会被硬编码 如果我在C或C++中这样做,我会说: #define GENERATE_REFERENCE(text) #text 我真的不在乎它是作为方法调用形成的,因为我已经在这里原型化了 C#中的“伪代码”描述了我正在尝试做的事情: public class MyClass { public void SayHel

我正在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();
    }
}
我的问题与建议的重复问题不同,因为我的问题来自一个对C#机制(新手)非常无知的地方。怀疑重复的问题意味着一个更高层次的理解,远远超出了我在问题中所展示的——我不知道怎么问这个问题。从我的搜索中,我永远不会找到这个答案

使用系统反射(C#6.0之前):

typeof(MyClass).GetMethod(“SayHello”).Name

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

nameof(SayHello)

c#6引入了一个名为
nameof
的新操作符,它消除了带有方法名称的硬编码字符串

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

在C#6之前

publicstaticstringgeneratereference(Expression

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

我会用这样的东西

System.Reflection.MethodBase.GetCurrentMethod().Name
并在需要时将方法的名称作为参数传递

干杯!

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

下面是一个依赖重载获得正确答案的示例。请注意,如果您的“real”方法都有自己的唯一参数,则不需要伪重载,可以完全避免
querymethodnameheloper
参数

// 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);
  }
}

此示例的优点是在编译时注入字符串(没有查找元数据的运行时开销),但它确实要求您保持方法名称同步(例如,如果重命名“real”
SayHello
,则还需要重命名helper
SayHello
)。幸运的是,如果您单击“重命名重载”复选框,重构对话框将为您做到这一点,但默认情况下它不会打开。

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

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

但这与使用“SayHello”并没有什么区别。您需要该方法的名称才能获取该方法的名称Add如何在c#6之前完成此操作为什么不作为dup关闭而不是发布答案?我认为您不需要。泛型参数用于具有该方法的类。事实上-comment deletedPossible duplicate仅在您从SayHello调用GenerateReference时才起作用,SayHello事实并非如此……我认为,如果我将CallerMemberNameAttribute调用放入GenerateReference,它将在提出问题时起作用。@silverglade仅当您从SayHello调用GenerateReference时才起作用,而在您的示例中,您不是。@Brian Rudolph,是的,现在我明白了。感谢您的澄清!您可以使用重载形式的SayHello它接受一个伪参数并返回一个由帮助程序生成的字符串。我稍后将尝试添加示例代码。我认为GetCurrentMethod比OP想要的更具限制性。这是一个很好的建议。它有两个缺点(除了
nameof
do以外的所有解决方案)--如果您更改
SayHello
的签名,它将导致编译器错误,并且它还有运行时开销。这些可能是可以接受的缺点。考虑到为服务调用生成url的OP用例,我想说编译器错误实际上是一个好处,它使这一点非常明确。至于运行时开销,我但是,除了编译时特性,如nameof或[CallerMemberName],我认为这与其他选项差不多。如果URL字符串需要不同的参数,编译器错误将无法修复URL字符串。实际上,我认为正确的方法是使用单一的真实来源,然后从中生成客户端和服务器代码……但这有点超出了最初的问题。
// 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);
  }
}
Action<string> del = this.SayHello;
string ret = del.Method.Name;