2008-09-24 87 views
15

考慮到調試數據文件可用(PDB)並通過使用System.Reflection或其他類似的框架,如Mono.Cecil,如何以編程方式檢索源文件名和行號,其中類型或聲明一個類型的成員。如何獲取源文件名和類型成員的行號?

例如,假設你編譯這個文件到一個程序:

C:\ MyProject的\ Foo.cs

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

如何做這樣的事情:

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

sourceFileName將包含「C:\ MyProject \ Foo.cs」和sourceLineNumber等於3.

更新:System.Diagnostics.StackFrame確實能夠獲取該信息,但僅限於當前執行調用堆棧的範圍。這意味着該方法必須首先被調用。我想獲得相同的信息,但沒有調用類型成員。

+0

有新的API來即用,無需使用PDB閱讀器更多,請參閱我的答案 – 2013-04-30 09:01:01

回答

7

通過使用由CCI Metadata Project提供的PDB閱讀器,它能夠提取給定類型的元件的碼位置。參見,例如,實施在的源代碼。

+0

Yann,CCI仍然是一件事,但Gallio項目已關閉。它的最後一個源代碼可以在GitHub上找到(https://github.com/Gallio),但是沒辦法告訴你指的是哪一部分。你能否考慮在這裏提供源代碼,或者指出你所指的實現在哪個文件中? – 2017-03-10 17:46:22

1

你可能會發現一些幫助,這些鏈接:

Getting file and line numbers without deploying the PDB files 也發現了這個以下post

「嗨,馬克,

下面會給你的代碼的行數(在源文件):

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

如果你有興趣,你可以瞭解你的日常活動,以及其中的所有來電者。

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 

這是非常方便的,如果你想有一個廣義的錯誤例程,因爲它 可以得到呼叫者的名字(這將是哪裏出現了錯誤)。

問候, 宏泰 MVP [Windows開始按鈕,關閉對話] 「

+2

不幸的是,StackTrace提供了有關當前調用堆棧的信息;而不是關於任意的外部成員。我想獲取信息而不實際運行該方法。 – 2008-09-30 07:45:35

+0

理查德,忙碌代碼鏈接已損壞。是否有任何更新的鏈接? – 2013-06-19 23:45:41

12

到目前爲止方法:

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); 
} 

Framework API其中填充參數(標有特殊屬性)在運行時, 看到更多my answer to this SO question

1

使用的方法之一如上所述,在構造函數中的屬性,你可以提供一切的源位置,可能有一個屬性 - 例如一個類。請參閱以下屬性類:

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 
{ 
    ... 
} 

的,你可以,例如寫:

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

輸出將是:

a:\develop\HWClassLibrary.cs\src\Tester\Program.cs(65): 
相關問題