4

Is there a way to include line numbers and file name in C#'s Console.WriteLine function?

For example, on the line 115 of file "myClass.cs" I have the statement

Console.WriteLine("Hello world");

I would like the output to be:

[myClass.cs][115]:  Hello world 
rae1
  • 6,066
  • 4
  • 27
  • 48
mLar
  • 2,967
  • 2
  • 22
  • 23
  • 1
    Really You want output like that? – Satpal Jan 22 '14 at 18:17
  • 3
    Take a look here: http://stackoverflow.com/questions/6369184/print-the-source-filename-and-linenumber-in-c-sharp – Christian Phillips Jan 22 '14 at 18:17
  • Do you want to MODIFY the Console.WriteLine behavior to do that or you just want to get the line numbers? For line numbers, check: http://stackoverflow.com/questions/4900744/is-there-a-way-to-get-the-current-line-number-when-executing-code-c-sharp – cvbarros Jan 22 '14 at 18:22

3 Answers3

18

If you're using C# 5, you can use caller information attributes to do this. For example:

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

Output:

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

Before C# 5, you're stuck with execution-time stack checking, which is less reliable due to inlining, and relies on the information being present at execution time. (It might not in a release build, for example, whereas the above will still work.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    +1 That's a *very* neat trick – rae1 Jan 22 '14 at 18:22
  • 2
    It is important to note that the **compiler** is doing the heavy lifting with these attributes. If you are using the C# 5 *compiler* you can have the beauty of these attributes, even when targeting previous framework versions (or versions which do not have these). For example, you may be creating a MVVM project for the Portable Framework and want to use `CallerMemberNameAttribute`, but it does not exist in that version of `System.Runtime.CompilerServices`. If you manually create the attribute and use it, the compiler will still honor and implement it. – Erik Jan 22 '14 at 20:10
0

You can examine the StackTrace using this constructor, get a StackFrame from it, and then call GetFileName() and GetFileLineNumber() on the StackFrame. Note that this will require the .pdb files to be available with the application.

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

Modified code from link:

using System.Diagnostics;

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

I would create a helper method for this and leverage the solution that Marc Gravell wrote about in this post: How do I get the current line number?

Something like...

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

Then in myClass.cs, just replace the call to Console.WriteLine with:

WriteLineHelper.WriteLine("Hello world.");
Community
  • 1
  • 1
ScottMB
  • 56
  • 3