2010-10-06 23 views
2

我们使用Debug.Assert向开发人员发送代码中的问题。我想添加错误发生的行号,但不能硬编码,因为这可能会改变,我们会忘记更新字符串。在Debug.Assert语句中插入行号

添加错误的行号会很方便。有任何想法吗?

回答

8

默认情况下,Debug.Assert已经包含堆栈跟踪信息:

当应用程序在用户界面模式下运行时,它会显示一个消息框,显示了文件和行号调用堆栈。

例子:

alt text

如果你没有看到在你的断言对话框的文件名或行号,则PDB文件(如编译生成)被丢失或无法访问。 PDB文件包含文件和行调试信息。

还有就是C/C++的__FILE____LINE__魔法宏在C#中没有真正的等价物,但如果你还想要断言对话外这一信息,你可以使用StackTrace类来得到它。这要求你有调试信息可用(上面提到的PDB文件)。既然你可能使用它来进行开发,这是一个安全的要求。

using System.Diagnostics; 

namespace Managed 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AssertWithCallSite(false, "Failed!"); 
     } 

     [Conditional("DEBUG")] 
     static void AssertWithCallSite(bool condition, string message) 
     { 
      if (!condition) 
      { 
       var callSite = (new StackTrace(1, true)).GetFrame(0); 

       string fileName = callSite.GetFileName(); 
       int lineNumber = callSite.GetFileLineNumber(); 

       string assertMessage = string.Format(
        "Assert at {0}:{1}:\n{2}", 
        fileName, 
        lineNumber, 
        message 
       ); 

       Debug.Assert(false, assertMessage); 
      } 
     } 
    } 
} 
2

看一看Whats the equivalent of LINE and FILE in C#

string currentFile=new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName(); 
int currentLine = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber(); 

一定要看看上面的文章,因为有一些注意事项要注意。

1

是的,这是可能的。请看System.Diagnostics命名空间中的StackTraceStackFrame

static string GetDiagnosticsInformationForCurrentFrame() 
{ 
    StackTrace st = new StackTrace(new StackFrame(true));   
    StackFrame sf = st.GetFrame(1); // we want the frame from where this method was called 

    return String.Format("File: {0}, Method: {1}, Line Number: {2}, Column Number: {3}", sf.GetFileName(), sf.GetMethod().Name, sf.GetFileLineNumber(), sf.GetFileColumnNumber()); 
} 

...

Debug.Assert(true, "Unexpected error occurred at " + GetDiagnosticsInformationForCurrentFrame()); 

编辑正如克里斯指出,你不能从Conditional返回类型。我已经改变了我的答案,以便GetDiagnosticsInformationForCurrentFrame始终可用。

+1

'有条件的'属性只对'void'方法有效,因为该方法甚至可能不存在于构建中。 – 2010-10-06 00:31:39

+0

@克里斯:我不知道,但当然是的,情况就是这样。谢谢你因为我的错误而拉我。在这种情况下,你的答案是更好的解决方案(刚投票)。 – Dennis 2010-10-06 00:40:24

1

C#6.0,UAP应用程序。这很有效

public static void Assert(bool val, string message, [CallerFilePath] string file = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int lineNumber = 0) 
    { 
     string msg = String.Format($"File: {file}, Method: {memberName}, Line Number: {lineNumber}\n\n{message}"); 
     Debug.Assert(val, msg); 


    }