开发者

Print the source filename and linenumber in C#

Is there any way to retrieve the current source filename and linenumber in C# code and print that value in the console output? Like LINE and FILE in C?

Please a开发者_StackOverflowdvise.

Many thanks


Anders Hejlsberg presented new API for that in BUILD keynote:

Print current file name, method name and line number

private static void Log(string text,
                        [CallerFilePath] string file = "",
                        [CallerMemberName] string member = "",
                        [CallerLineNumber] int line = 0)
{
    Console.WriteLine("{0}_{1}({2}): {3}", Path.GetFileName(file), member, line, text);
}

Test:

Log(".NET rocks!");

Output:

Program.cs_Main(11): .NET rocks!

What's going on here?

You define a method with optional parameters and decorate them with special attributes. If you call method without passing actual arguments (leave defaults) - the Framework populates them for you.


This answer is outdated! See @taras' answer for more recent information.


No constant :(

What you can do is a lot uglier :

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

Works only when PDB files are available.


You can use the StackTrace object from the System.Diagnostics namespace but the information will only be available if the PDB files are there.

PDB files are generated by default for both the Debug and Release builds the only difference is that Debug is setup to generate a full debug info where as the Release build is setup to only generate a pdb (full/pdb-only).

Console.WriteLine(new StackTrace(true).GetFrame(0).GetFileName());

Console.WriteLine(new StackTrace(true).GetFrame(0).GetFileLineNumber());


There are no constants defined for that as of now.

The .NET way of doing it is using StackTrace class.

It however works only for Debug builds. So in case you use it, you can have the code using StackTrace between

#if DEBUG
    //your StackTrace code here
#endif

You can read about using #if preprocessors for your DEBUG vs. RELEASE builds in the following Stackoverflow thread.

C# if/then directives for debug vs release

EDIT: Just in case you still need this debugging information in release builds, read the following answer on Stackoverflow:

Display lines number in Stack Trace for .NET assembly in Release mode


If you want some more internal detail, but you don't specifically need filename and line number, you can do something like this:

System.Diagnostics.Debug.Print(this.GetType().ToString() + " My Message");

This has an advantage over printing out the filename in that if you put this in a parent class, it will print out the child class name that is actually running the code.


If you wanted to write your own version of Debug.Assert, then here's a more complete answer:

// CC0, Public Domain
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System;

public static class Logger {
    [Conditional("DEBUG")]  
    public static void Assert(bool condition, string msg,
            [CallerFilePath] string file = "",
            [CallerMemberName] string member = "",
            [CallerLineNumber] int line = 0
            )
    {
        // Debug.Assert opens a msg box and Trace only appears in
        // a debugger, so implement our own.
        if (!condition)
        {
            // Roughly follow style of C# error messages:
            // > ideone.cs(14,11): error CS1585: Member modifier 'static' must precede the member type and name
            Console.WriteLine($"{file}({line}): assert: in {member}: {msg}");
            // Or more precisely match style with a fake error so error-parsing tools will detect it:
            // Console.WriteLine($"{file}({line}): warning CS0: {msg}");
        }
    }
}

class Program {
    static void Main(string[] args) {
        Logger.Assert(1+1 == 4, "Why not!");
    }
}

Try it online.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜