C# 在不解析任何变量或使用引用的情况下在接收方法中获取调用方法、行号、class 文件和方法名称等?
C# Get the calling method's, line number, class file and method name, etc, in the receiving method without parsing any variables or using references?
(已解决)
我有自己的class库,是我在编程过程中不断开发、迭代和修改的,它包含了我经常使用的大量方法。例如,我有一个使用 class 和 B_Core.WriteDebug(string);
从任何 class 调用的方法。
此方法目前仅采用我编写的任何文本,并允许我使用自己的 库 .[=20 在 classes 中不包含 System.Diagnostics
=]
这有时会导致我只想知道一个数字的情况,它可能类似于 B_Core.WriteDebug(integer.ToString());
。作为一名程序员,我确实尝试始终包含一个 参考点 ,但当我错过它时,有时我只会得到一个 行 在调试输出中说“4”或类似的东西。
所以,我目前正在尝试对这种方法进行适当的修正。目前我唯一的想法是将 StackTrace 解析为该方法。
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);
}
这行得通,但它需要我将 using System.Diagnostics
添加到每个 class 将使用 B_Core.WriteLine()
。这可能会导致一些毫无意义的书面添加,它也是 class 允许轻松访问 Debug.WriteLine()
,这消除了我为此拥有自己的方法的部分原因在图书馆.
它还要求我实际解析 StackTrace,当我只是想知道一个简单的问题以进行故障排除或类似的事情时,添加更多要写的东西。
理想的场景应该是这样的:
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);
}
我可以通过引用调用方法本身来获取数据。所以我的问题是有什么方法可以做这样的事情,而不需要在 调用方法的 class 上添加额外的引用,并且希望不必解析任何其他 对象到方法?
感谢您对此的任何见解。
此致!
解决,感谢Fildor的评论。 Victor 的回答也很好,可能更接近实际问题。但我决定使用 Fildor 的推荐。
此时的方法是这样的:
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
}
您可以让假设的 Caller 对象进入堆栈:
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)
是最后一帧,您的 WriteDebug
方法。使用上一帧,您正在使用调用方方法。
您可以通过使用属性来实现:
调用的函数名称:CallerMemeberNameAttribute
来电线路号码:CallerLineNumberAttribute
(已解决)
我有自己的class库,是我在编程过程中不断开发、迭代和修改的,它包含了我经常使用的大量方法。例如,我有一个使用 class 和 B_Core.WriteDebug(string);
从任何 class 调用的方法。
此方法目前仅采用我编写的任何文本,并允许我使用自己的 库 .[=20 在 classes 中不包含 System.Diagnostics
=]
这有时会导致我只想知道一个数字的情况,它可能类似于 B_Core.WriteDebug(integer.ToString());
。作为一名程序员,我确实尝试始终包含一个 参考点 ,但当我错过它时,有时我只会得到一个 行 在调试输出中说“4”或类似的东西。
所以,我目前正在尝试对这种方法进行适当的修正。目前我唯一的想法是将 StackTrace 解析为该方法。
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);
}
这行得通,但它需要我将 using System.Diagnostics
添加到每个 class 将使用 B_Core.WriteLine()
。这可能会导致一些毫无意义的书面添加,它也是 class 允许轻松访问 Debug.WriteLine()
,这消除了我为此拥有自己的方法的部分原因在图书馆.
它还要求我实际解析 StackTrace,当我只是想知道一个简单的问题以进行故障排除或类似的事情时,添加更多要写的东西。
理想的场景应该是这样的:
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);
}
我可以通过引用调用方法本身来获取数据。所以我的问题是有什么方法可以做这样的事情,而不需要在 调用方法的 class 上添加额外的引用,并且希望不必解析任何其他 对象到方法?
感谢您对此的任何见解。
此致!
解决,感谢Fildor的评论。 Victor 的回答也很好,可能更接近实际问题。但我决定使用 Fildor 的推荐。
此时的方法是这样的:
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
}
您可以让假设的 Caller 对象进入堆栈:
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)
是最后一帧,您的 WriteDebug
方法。使用上一帧,您正在使用调用方方法。
您可以通过使用属性来实现:
调用的函数名称:CallerMemeberNameAttribute
来电线路号码:CallerLineNumberAttribute