I\'m writing a C# program using Visual Studio 2010 where I want to write out certain events to a log file and include the line number the code was on when that happened.
One option would be to use the StackTrace class, like so
[Conditional("DEBUG")]
public static void DebugPrintTrace()
{
StackTrace st = new StackTrace(true);
StackFrame sf = st.GetFrame(1);
Console.WriteLine("Trace "
+ sf.GetFileName() + " "
+ sf.GetMethod().Name + ":"
+ sf.GetFileLineNumber() + "\n");
}
No, C# doesn't have a macro preprocessor or any meta programming features, so there are no "Compile time" solutions in the entire language. But there are 3rd party macro languages out there that you can use, if you have to, but of course it complicates the build process, Visual Studio won't just figure out how to built it by itself.
You can even use the C preprocessor if you want it. (assuming MSVC compiler)
cl.exe /TC /P /C /EP something.cs > something.raw.cs
cl.exe
is the C compiler/TC
tells the C compiler to treat all files as C sources despite their extensions/P
tells the C compiler to only preprocess the file do not compile it/C
preserves the comments/EP
prevents the compiler from generating #line directives, that the C# compiler wouldn't understandThis will allow you to use #include
, #define
and #if
as well as __FILE__
and __LINE__
in your C# program, but again you have to set up Visual Studio to do this additional compilation step, or use a different build system.
CAVEATS: This is NOT an answer to the OP. I know that. But people looking for something similar may find this page.
But VS 2015, C#, .NET Core or .NET 4.5 allow:
using System.Runtime.CompilerServices;
using System.Diagnostics;
public static String CurrentLocation(
[CallerFilePath] string file = null,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string method = null)
{
String location = file;
if (lineNumber != 0)
{
location += "(" + lineNumber.ToString() + ")";
}
if (!String.IsNullOrWhiteSpace(method))
{
location += ": " + method;
}
if (!String.IsNullOrWhiteSpace(location))
{
location += ": ";
}
return location;
}
[UPDATED USAGE]
With usage something like:
Console.Error.WriteLine(CurrentLocation() + "some message");
or
Debug.WriteLine(CurrentLocation() + "some message");
In my opinion, line numbers are the wrong approach. Let me explain:
How unique is line number 175? Even if you find a solution, the next question is: which file was it? And it will repeat: if you know the file, you'll ask yourself: which version of the file was it? And you'll integrate the revision number of your source control system. Once you did that, the question will come up: who was calling that code.
If you're debugging an exception, use a debugger and break on first chance exceptions.
If you're analyzing a performance issue, line numbers don't matter, anything unique will do. Try a memory profiler.
If your methods are too long to identify the problems, refactor your code and make the methods shorter. With short methods, you can use an AOP framework like PostSharp with its logging aspect to achieve at least the CallerMemberName
feature. It's available down to .NET 2.0 and it's very easy to add logging and remove logging, not like deleting single lines in your code.