1

I'm a Visual C++.net programmer that converted to C# about a year ago, and I really miss __FILE__, and __LINE__. To replace __FILE__, I wrote a nice function to return class.method, which is awesome, but there is no suitable alternative for __LINE__ (correct me if I'm wrong!).

I understand the language difference and technical limitations, and the reasoning, and all that stuff.

What I'm asking is this:

Is it practical, or even possible, to write some visual studio extension (that all of our developers would have installed), that would allow for us to define some type of token (~~LINE~~ or something), that we could have text replacement or something switch that symbol to the actual VS line number, when compiled into an executable?

My knowledge of extensions programming is minimal, I do not know the ext. systems limitations.

Edit for clarification:

In C++, __FILE__, once compiled, will return the current file you wrote your code in, and __LINE__, your current line. This is important because all of our logging systems (10+ years old), all require a char* for the file, and an int for the line, we're logging from.

C# cannot produce these two 'tokens' like C++ can.

As an example:

LoggingService.LogException(e, "file.cs", 1234);  

is what I want to get compiled into my executable, and

LoggingService.LogException(e, ~~MYFILE~~, ~~MYLINE~~); 

is what I want my code to look like, and saved on disk. I have a suitable alternative to get the file, but I don't have one to get the line.

Edit 2:

These our release builds, without debugging symbols. Our product installs would have to be hundreds of megabytes larger in order to accomidate this fix, which is out of the question.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
greggorob64
  • 2,487
  • 2
  • 27
  • 55
  • are you looking for a string.Replace Method() ?... also if you want to replace a line with a blank line also look into Environment.NewLine method as well I am a bit confused on what you are truly asking.. – MethodMan Jul 12 '12 at 18:20
  • What for? If you want to trace a call stack, the run-time does that for you. – Seva Alekseyev Jul 12 '12 at 18:23
  • Edited for clarification. Its in order for our C# applications to work with our legacy error logging service (enterprise-level application). – greggorob64 Jul 12 '12 at 18:24
  • Also, release builds have very poor call stack information. – greggorob64 Jul 12 '12 at 18:25
  • I'm almost positive that I've used some replacement type thing for `_LINE_`, but I can't recall what it was – Earlz Jul 12 '12 at 18:25
  • There are FLOSS preprocessors such as MCPP out there. Why not use one of these as the basis for your solution? – 0xC0000022L Jul 12 '12 at 18:25
  • Duplicate of http://stackoverflow.com/questions/696218/do-line-file-equivalents-exist-in-c ? – Surfbutler Jul 12 '12 at 18:26
  • almost sounds like you want to use some string.Format method and pass in params for the formatting is this what you are wanting to do..? – MethodMan Jul 12 '12 at 18:27
  • @DJ, I'm using a string.format to use CurrentClass.CurrentMethod (via reflection for the line alternative), but there is no way using reflection, in a release build, to get your line. – greggorob64 Jul 12 '12 at 18:38
  • @Surfbutler, I don't think this is a true duplicate. I acknowledged no current alternative exists. The intent of this question was to ask if its plausible to write an extension to create something like this. All of the comments insofar have just not addressed the question asked. – greggorob64 Jul 12 '12 at 18:39

4 Answers4

3

Caller Information is coming in .NET 4.5. This will be compiled, a big improvment over having to examine the stacktrace manually:

http://msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx

public void LogException(Exception ex,
        [CallerFilePath] string filePath = "",
        [CallerLineNumber] int lineNumber = 0)
{
    // Log it!
}

Thanks to the compiler magic, this would be called as:

LoggingService.LogException(e);
roken
  • 3,946
  • 1
  • 19
  • 32
  • This looks promising, we're currently at 4.0, but will be jumping to 4.5 soon. – greggorob64 Jul 12 '12 at 18:43
  • Yes, this is exactly it -- as the doc says "Caller Info values are emitted as literals into the Intermediate Language (IL) at compile time." So debug won't matter and no runtime penalty -- nice. – Hogan Jul 12 '12 at 18:49
2

You can simply run all C# code through C preprocessor first and than compile results. You will need to change build rules for CS files to do that.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Why would you do this when you can use stack frame? – Hogan Jul 12 '12 at 18:28
  • @Hogan, I would not, it is simply reply to original question. I suspected that OP wanted it for logging exceptions, but maybe there was some other reasons (likely not after edits of the question). – Alexei Levenkov Jul 12 '12 at 18:36
  • Alexia, I think this might be a good example. When we compile our project, we might run the entire app through a preprocessor. @Hogan, I don't have debug symbols, no stack frame. – greggorob64 Jul 12 '12 at 18:41
1

Note: If you are processing exceptions the stack frame is in the exception, so this won't be needed. I used this once to store line and file information with a logging system and that is the only use case I can think of -- but it is "not so fast".

WARNING: If you don't have symbols in your release build some of this information will not be available.

using System;
using System.Diagnostics ;

StackTrace st=new StackTrace (0,true);

StackFrame sf=new StackFrame ();
sf=st.GetFrame (0);
Console.WriteLine ("FileName: {0}",sf.GetFileName ());
Console.WriteLine ("Line Number: {0}",sf.GetFileLineNumber ());
Console.WriteLine ("Function Name: {0}",sf.GetMethod ());

There is also column and type and some other stuff in there... look here for more.

http://msdn.microsoft.com/en-us/library/system.diagnostics.stackframe.aspx

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • Unfrotunately, we do not have symbols. Our app runs on the plant for and install size has been paramount. Symbols are out of the question. I do use this method for debug builds though! – greggorob64 Jul 12 '12 at 18:40
0

The line is in the exception's stack trace. but rather than extracting it, I think you should log the entire stack trace as it has other useful information for debugging (plus the line number is sometimes a few lines off, due to preprocessor statements i believe)

I would highly recommend ELMAH if you're doing ASP.Net web applications either in Web Forms or MVC. It takes care of all of that logging

arserbin3
  • 6,010
  • 8
  • 36
  • 52