Учитывая, что файл отладочных данных доступен (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 действительно может получить эту информацию, но только в рамках текущего стека вызовов. Это означает, что метод должен быть вызван первым. Я хотел бы получить ту же информацию, но без вызова члена типа.
Вы когда-нибудь понимали это? Ответы полностью упускают из виду суть вашего вопроса, а именно получение имени файла и номера строки для произвольного члена. Не для текущего ... Гарольд - самый близкий, но требует, чтобы каждый потенциальный член был украшен этим атрибутом ...





вы можете найти помощь по этим ссылкам:
Получение номеров файлов и строк без развертывания файлов PDB также нашел это после Почта
"Привет Марк,
Следующее даст вам номер строки вашего кода (в исходный файл):
Dim CurrentStack As System.Diagnostics.StackTrace
MsgBox (CurrentStack.GetFrame(0).GetFileLineNumber)
Если вам интересно, вы можете узнать о распорядке, который вы in, а также все его вызывающие.
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, диалоговое окно "Завершение работы"] "
К сожалению, StackTrace предоставляет информацию о текущем стеке вызовов; а не о произвольном внешнем члене. Я хотел бы получить информацию, не выполняя метод.
Ричард, ссылка на код занятости не работает. Есть ли где-нибудь обновленная ссылка?
Актуальный метод:
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, который заполняет аргументы (отмеченные специальными атрибутами) во время выполнения,
подробнее в мой ответ на этот ТАК вопрос
Доступно только для .Net 4.5. Огромный недостаток для корпоративных проектов.
Я думаю, вы в корне неправильно поняли вопрос. Вы показали, как получить информацию о вызывающем абоненте, но вопрос заключается в том, как запросить это для любого символа. См. Комментарий Яна Тревина к ответу Ричарда.
Используя один из описанных выше методов, внутри конструктора атрибута вы можете указать исходное местоположение всего, что может иметь атрибут - например, класса. См. Следующий класс атрибута:
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):
для этого есть новый API, больше не нужно использовать PDB-ридер, см. мой ответ