C# 如何获取类型成员的源文件名和行号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/126094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:45:22  来源:igfitidea点击:

How to get the source file name and the line number of a type member?

提问by Yann Trevin

Considering that the debug data file is available (PDB) and by using either System.Reflectionor another similar framework such as Mono.Cecil, how to retrieve programmatically the source file name and the line number where a type or a member of a type is declared.

考虑到调试数据文件可用 (PDB) 并通过使用System.Reflection或其他类似框架(例如Mono.Cecil ),如何以编程方式检索源文件名和类型或类型成员所在的行号宣布。

For example, let's say you have compiled this file into an assembly:

例如,假设您已将此文件编译为程序集:

C:\MyProject\Foo.cs

C:\MyProject\Foo.cs

1:    public class Foo
2:    {
3:       public string SayHello()
4:       {
5:           return "Hello";
6:       }
7:    }

How to do something like:

如何做这样的事情:

MethodInfo methodInfo = typeof(Foo).GetMethod("SayHello");
string sourceFileName = methodInfo.GetSourceFile(); // ?? Does not exist!
int sourceLineNumber = methodInfo.GetLineNumber(); // ?? Does not exist!

sourceFileName would contain "C:\MyProject\Foo.cs" and sourceLineNumber be equal to 3.

sourceFileName 将包含“C:\MyProject\Foo.cs”并且 sourceLineNumber 等于 3。

Update: System.Diagnostics.StackFrameis indeed able to get that information, but only in the scope of current executing call stack. It means that the method must be invoked first. I would like to get the same info, but without invoking the type member.

更新:System.Diagnostics.StackFrame确实能够获得该信息,但仅限于当前执行调用堆栈的范围内。这意味着必须首先调用该方法。我想获得相同的信息,但不调用类型成员。

回答by Richard

you might find some help with these links:

您可能会通过这些链接找到一些帮助:

Getting file and line numbers without deploying the PDB filesalso found this following post

在不部署 PDB 文件的情况下获取文件和行号还发现了以下帖子

"Hi Mark,

“嗨,马克,

The following will give you the line number of your code (in the source file):

以下将为您提供代码的行号(在源文件中):

Dim CurrentStack As System.Diagnostics.StackTrace
MsgBox (CurrentStack.GetFrame(0).GetFileLineNumber)

In case you're interested, you can find out about the routine that you're in, as well as all its callers.

如果您有兴趣,可以了解您所在的例程及其所有调用者。

Public Function MeAndMyCaller As String
    Dim CurrentStack As New System.Diagnostics.StackTrace
    Dim Myself As String = CurrentStack.GetFrame(0).GetMethod.Name
    Dim MyCaller As String = CurrentStack.GetFrame(1).GetMethod.Name
    Return "In " & Myself & vbCrLf & "Called by " & MyCaller
End Function

This can be very handy if you want a generalised error routine because it can get the name of the caller (which would be where the error occurred).

如果您想要一个通用的错误例程,这会非常方便,因为它可以获得调用者的名称(这将是发生错误的地方)。

Regards, Fergus MVP [Windows Start button, Shutdown dialogue] "

问候,弗格斯 MVP [Windows 开始按钮,关机对话框]”

回答by illegal-immigrant

Up to date method:

最新方法:

private static void Log(string text,
                        [CallerFilePath] string file = "",
                        [CallerMemberName] string member = "",
                        [CallerLineNumber] int line = 0)
{
    Console.WriteLine("{0}_{1}({2}): {3}", Path.GetFileName(file), member, line, text);
}

New Framework APIwhich populates arguments (marked with special attributes) at runtime, see more in my answer to this SO question

Framework API其填充参数(标有特殊属性)在运行时,看到在我回答这个问题的SO

回答by Harald Hoyer

Using one of the methods explained above, inside the constructor of an attribute, you can provide the source location of everything, that may have an attribute - for instance a class. See the following attribute class:

使用上面解释的方法之一,在属性的构造函数中,您可以提供可能具有属性的所有内容的源位置 - 例如类。请参阅以下属性类:

sealed class ProvideSourceLocation : Attribute
    {
        public readonly string File;
        public readonly string Member;
        public readonly int Line;
        public ProvideSourceLocation
            (
            [CallerFilePath] string file = "",
            [CallerMemberName] string member = "",
            [CallerLineNumber] int line = 0)
        {
            File = file;
            Member = member;
            Line = line;
        }

        public override string ToString() { return File + "(" + Line + "):" + Member; }
    }


[ProvideSourceLocation]
class Test
{
   ...
}

The you can write for instance:

你可以写例如:

Console.WriteLine(typeof(Test).GetCustomAttribute<ProvideSourceLocation>(true));

Output will be:

输出将是:

a:\develop\HWClassLibrary.cs\src\Tester\Program.cs(65):