For logging purposes
__LINE__
__FILE__
were my friends in C/C++. In Java to get that information I had to throw an exception and catch it. Why are these old standbys so neglected in the modern programming languages? There is something magical about their simplicity.
It is uglier, but you can do something like this in C#using the StackTrace and StackFrame classes:
Of course, this comes with some overhead.
Because the stack trace contains most of what you need. It will not give you the name of the file but it will give you the class/method name. It also contains the line number. It is not neglected it is automatic. You just need to throw an exception like you do it in Java
The closest thing to those is the fact that you can create a
StackTrace
object and find out the name of the method at the top of the stack, so you can get close to the functionality of the__FUNCTION__
macro.To reduce the cost of typing this out by hand, and also the runtime code, you can write a helper method:
Note how we get frame 1, as frame 0 would be
LogMethodName
itself. By marking it as Conditional("Debug") we ensure that the code is removed from release builds, which is one way to avoid the runtime cost where it may not be needed.Here's a way to get the line number: http://askville.amazon.com/SimilarQuestions.do?req=line-numbers-stored-stack-trace-C%2523-application-throws-exception
If you use log4net, you can get the line number and file name in your logs, but:
There are already some suggestions to achieve what you want. Either use the StackTrace object or better log4net.
In Java to get that information I had to throw an exception and catch it.
That's not quite true. You can have it without throwing exceptions, too. Have a look to log4j. It even logs your method and class name, without polluting your code with hard coded strings containing the current method name (at least I have seen this in some occasions).
Why are these old standbys so neglected in the modern programming languages?
Java and C# don't make use (in the latter: excessive use) of preprocessors. And I think it's good. Abusing preprocessors to make unreadable code is very easy. And if programmers can abuse some technique ... they will abuse it.
Just a note about performance, which is very likely to be the next thing, which pops up in your mind:
If you use StackTrace or log4net you will always will read or hear that it is slow, because it uses Reflection. I am using log4net and I never encountered logging as a performance bottle neck. If it would be, I can declaratively deactivate (parts of) logging -- without changing the source code. That's pure beauty compared to delete all the logging lines in C/C++ code! (Besides: If performance is a primary goal, I would use C/C++ ... it will never die despite of Java and C#.)
With Caller Information (introduced in .NET 4.5) you can create the equivalent of
__LINE__
and__FILE__
in C#:The only thing to remember is that these are functions and not compiler directives.
So for example:
If you were to use this in practise then I'd suggest different names. I've used the C/C++ names just to make it clearer what they are returning, and something like
CurrentLineNumber()
andCurrentFileName()
might be better names.The advantage of using Caller Information over any solution that uses the
StackTrace
is that the line and file information is available for both debug and release.