2

(SOLVED) I have my own class library that I've been successively developed, iterated and modified during my programming course, it contains a multitude of methods that I use on the regular. For example I have a method that is called from any class using the class with B_Core.WriteDebug(string);. This method currently only takes whatever text I've written, and allows me to not include the System.Diagnostics in the classes using my own library.

This can, on occassion lead to situations where I simply want to know a single digit, and it could be something like B_Core.WriteDebug(integer.ToString());. As I've developed as a programmer I do try to always include a reference point, but when I miss it, I sometimes just get a line in the Debug output saying "4" or something along those lines.

So, I am currently trying to make a decent correction to this method. Currently the only idea I have is to parse a StackTrace to the method.

public static void WriteDebug(string text, StackTrace trace) {
    var frame = trace.GetFrame(0);
    string writeString = "Line: " + 
                            frame.GetFileLineNumber() + " | " + 
                            frame.GetFileName() + " | " + 
                            frame.GetMethod() + " | Text:\n";
    writeString += text;

    // Debug output => Line: x | File: Program.cs | Main | Text:
    //                 Hello world!
    Debug.WriteLine(writeString);
}

This'll work, but it requires me to add the using System.Diagnostics to each class that is gonna use the B_Core.WriteLine(). This can result in some pointless written additions, it's also the class granting easy accessibility to Debug.WriteLine(), which removes part of my reason for having my own method for this in the library.

It also requires me to actually parse the StackTrace, adding more things to write when I simply want to know a simple thing for troubleshooting or similar.

The ideal scenario would be something like:

public static void WriteDebug(string text) { //Removed the StackTrace parse
    var frame = Caller.trace.GetFrame(0);    //Added a hypothetical Caller object
    string writeString = "Line: " + 
                            frame.GetFileLineNumber() + " | " + 
                            frame.GetFileName() + " | " + 
                            frame.GetMethod() + " | Text:\n";
    writeString += text;

    // Debug output => Line: x | File: Program.cs | Main | Text:
    //                 Hello world!
    Debug.WriteLine(writeString);
}

Where I'd get the data by just referencing the calling method itself. So my question is there any way to do something like this without adding extra references atop the calling method's class as well as hopefully not having to parse any other object to the method?

Thanks for any insight into this.

Best regards!

Solution, thanks to Fildor in the comments. The answer by Victor is also good and might be closer to the actual question. But I've decided to use Fildor's recommendation.

This is the method at this time:

public static void WriteTrace(string text, bool printTrace = true,
    [System.Runtime.CompilerServices.CallerMemberName] string membName = "",
    [System.Runtime.CompilerServices.CallerFilePath] string filePath = "",
    [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0) {

            
    if (printTrace) 
        Trace.Write("Line: " + 
            lineNumber + " | " + 
            filePath.Split('\\').Last() + " | " + 
            membName + ":\t"
        );
    Trace.WriteLine(text);
    //Output => Line: 208 | BMenu.cs | MoveSelection:   0
}
5
  • There are Attributes for that. CallerMemeberNameAttribute, CallerLineNumberAttribute and CallerFilePathAttribute Commented May 16, 2022 at 11:45
  • See here. Commented May 16, 2022 at 11:46
  • 2
    Another tip would be to use an actual Logging Framework. Commented May 16, 2022 at 11:50
  • @Fildor This worked perfectly. Still in C# basic programming, and I have other things that I need to focus on than figuring out how to add another framework at the moment :P Commented May 16, 2022 at 16:46
  • @Fildor Want to make it an answer so I can set it as the solution? Commented May 16, 2022 at 16:53

2 Answers 2

4

You can achieve this by using Attributes:

FunctionName that called: CallerMemeberNameAttribute

Caller File: CallerFilePathAttribute

Caller Line Number: CallerLineNumberAttribute

Example of how to use them:

using System;
using System.Runtime.CompilerServices;
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine(LogMethod("Example"));
    }
    
    public static string LogMethod(string logMessage, [CallerMemberName] string methodName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
    {
        return $"Called by `{methodName}` in `{System.IO.Path.GetFileName(filePath)}` at line `{lineNumber}` with message `{logMessage}`";
    }
}

The code above will output something like this:

Called by `Main` in `Program.cs` at line `8` with message `Example`

Fiddle: https://dotnetfiddle.net/yNZW94 (in the Fiddle you won't get a filename, though)

Sign up to request clarification or add additional context in comments.

Comments

0

You can get your hypothetical Caller object going up on the stack:

public static void WriteDebug(string text)
{
    var stackTrace = new StackTrace();
    var frame = stackTrace.GetFrame(stackTrace.FrameCount - 2);

    string writeString = "Línea: " +
        frame.GetFileLineNumber() + " | " +
        frame.GetFileName() + " | " +
        frame.GetMethod() + " | Text:\n";
    writeString += text;

    // Salida de depuración => Línea: x | Archivo: Program.cs | Principal | Texto:
    // ¡Hola mundo!
    Debug.WriteLine(writeString);
}

stackTrace.GetFrame(stackTrace.FrameCount - 1) is the last frame, your WriteDebug method. Using the previous frame you are using the caller method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.