2013-04-23 68 views
3

我用下面的语句来打印当前函数的名称(例如,一个事件处理程序)在Visual Studio Output窗口(2010):替代在C#中内联?

Debug.Write(MethodBase.GetCurrentMethod().Name); 

如果我把这个实用的功能,例如内作为DisplayFunctionName(),而不是调用它的父函数,每次显示的内容是“DisplayFunctionName” - 没有意外!

我知道C#中没有内联,但是在这种情况下是否存在另一种解决方案,即使用“片段”,以便不必重复这些语句?

+2

“在C#中没有内联?”。醒来:-) – 2013-04-23 16:56:14

+1

是的,肯定有内联在C#中。如果没有内联,你不会获得这种性能... – evanmcdonnal 2013-04-23 16:56:55

+0

我的意思是“C++类型宏”意义上的内联。 – Sabuncu 2013-04-23 17:13:56

回答

10

您可以使用CallerMemberNameAttribute来显示来电者的姓名。

public void WriteDebug(string message, [CallerMemberName] string memberName = "") 
{ 
    Debug.Write("[" + memberName + "] " + message); 
} 

还有CallerLineNumberAttributeCallerFilePathAttribute您可以使用包含这些信息的详细诊断。这些属性是described in detail on MSDN。与该方法上的[Conditional("DEBUG")]相结合,您可以在调试期间提供大量信息,这些信息在发布版本中完全消除。

我知道C#中没有内联,但是在这种情况下还有另一种解决方案,使用'snippets',以便不必重复这些语句?

请注意,这与“内联”直接无关,与获取调用成员的诊断信息一样多。这就是说,JIT在您的代码运行时绝对执行内联,这是C#具有良好性能的主要原因之一。

这需要Visual Studio 2012,因为它使用该版本中的新编译器功能来运行。


如果您使用的是较旧的编译器,另一种方法是使用​​拉出堆栈跟踪信息。然而,这对性能有相当大的影响,所以它不是在紧密的循环中使用,至少不是在生产环境中使用,尽管它在调试期间仍然可用于诊断。

string callingMethodName = (new StackTrace()).GetFrame(1).GetMethod().Name; 
+2

有关更多详细信息,请参阅http://msdn.microsoft.com/en-us/library/hh534540.aspx。 – DeCaf 2013-04-23 16:57:59

+0

里德,谢谢+1。我有Visual Studio 2010,并在我的项目中使用.NET 4.0。 CallerMemberName未定义。将安装.NET 4.5修复这种情况?搜索结果表明,VS 2010可能无法实现。 – Sabuncu 2013-04-23 17:27:51

+1

@Sabuncu您需要使用VS 2012 - 这是一个编译器功能。您仍然可以定位.NET 4(如果您自己实现这些属性),因为它纯粹是一种编译器功能,但它在VS 2010中不起作用。 – 2013-04-23 17:30:12