【问题标题】:How to include line number and file name Console.WriteLine output? [duplicate]如何包含行号和文件名 Console.WriteLine 输出? [复制]
【发布时间】:2014-01-22 18:15:06
【问题描述】:

有没有办法在 C# 的 Console.WriteLine 函数中包含行号和文件名?

例如,在文件“myClass.cs”的第 115 行,我有这样的声明

Console.WriteLine("Hello world");

我希望输出是:

[myClass.cs][115]:  Hello world 

【问题讨论】:

标签: c# visual-studio


【解决方案1】:

如果您使用的是 C# 5,则可以使用 caller information attributes 来执行此操作。例如:

using System;
using System.IO;
using System.Runtime.CompilerServices;

public class Test
{
    static void Log(string message,
                    [CallerFilePath] string file = null,
                    [CallerLineNumber] int line = 0)
    {
        Console.WriteLine("{0} ({1}): {2}", Path.GetFileName(file), line, message);
    }

    static void Main()
    {
        Log("Hello, world");
        Log("This is the next line");
    }
}

输出:

Test.cs (16): Hello, world
Test.cs (17): This is the next line

在 C# 5 之前,您会遇到执行时堆栈检查,由于内联,这种检查不太可靠,并且依赖于执行时存在的信息。 (例如,它可能不在发布版本中,而上述方法仍然有效。)

【讨论】:

  • +1 这是一个非常巧妙的技巧
  • 请注意,编译器 正在使用这些属性完成繁重的工作。如果您使用的是 C# 5 编译器,那么即使针对以前的框架版本(或没有这些属性的版本),您也可以拥有这些属性的优点。例如,您可能正在为 Portable Framework 创建一个 MVVM 项目并希望使用CallerMemberNameAttribute,但它在该版本的System.Runtime.CompilerServices 中不存在。如果你手动创建属性并使用它,编译器仍然会尊重并实现它。
【解决方案2】:

您可以使用this constructor 检查StackTrace,从中获取StackFrame,然后在StackFrame 上调用GetFileName()GetFileLineNumber()。请注意,这需要应用程序提供 .pdb 文件。

http://social.msdn.microsoft.com/Forums/en-US/a58dc2a0-0612-407b-8cbe-10f1784ba85a/how-to-retreive-the-line-number-and-file-name-of-c-source-code?forum=csharplanguage

来自链接的修改代码:

using System.Diagnostics;

var StackTrace = new System.Diagnostics.StackTrace(true);
var StackFrame = StackTrace.GetFrame(0);
string FileName = StackFrame.GetFileName();
string LineNumber = StackFrame.GetFileLineNumber().ToString();

【讨论】:

    【解决方案3】:

    我会为此创建一个辅助方法,并利用 Marc Gravell 在这篇文章中所写的解决方案: How do I get the current line number?

    类似...

    public static class WriteLineHelper
    {
        public static void WriteLine(string message,
            [CallerLineNumber] int lineNumber = 0,
            [CallerMemberName] string caller = null)
        {
            Console.WriteLine(string.Format("[{0}][{1}] : {2}, caller, lineNumber, message);
        }
    }
    

    然后在 myClass.cs 中,只需将 Console.WriteLine 的调用替换为:

    WriteLineHelper.WriteLine("Hello world.");
    

    【讨论】:

    • ...或者基本上是 Jon Skeet 所说的。
    猜你喜欢
    • 2022-12-03
    • 2017-01-10
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多