Как получить имя исходного файла и номер строки члена типа?

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

для этого есть новый API, больше не нужно использовать PDB-ридер, см. мой ответ

illegal-immigrant 30.04.2013 13:01

Вы когда-нибудь понимали это? Ответы полностью упускают из виду суть вашего вопроса, а именно получение имени файла и номера строки для произвольного члена. Не для текущего ... Гарольд - самый близкий, но требует, чтобы каждый потенциальный член был украшен этим атрибутом ...

Douglas Gaskell 11.10.2019 00:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
19
2
15 343
3

Ответы 3

вы можете найти помощь по этим ссылкам:

Получение номеров файлов и строк без развертывания файлов 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 предоставляет информацию о текущем стеке вызовов; а не о произвольном внешнем члене. Я хотел бы получить информацию, не выполняя метод.

Yann Trevin 30.09.2008 11:45

Ричард, ссылка на код занятости не работает. Есть ли где-нибудь обновленная ссылка?

Nate Cook 20.06.2013 03:45

Актуальный метод:

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. Огромный недостаток для корпоративных проектов.

Kobor42 25.09.2013 14:26

Я думаю, вы в корне неправильно поняли вопрос. Вы показали, как получить информацию о вызывающем абоненте, но вопрос заключается в том, как запросить это для любого символа. См. Комментарий Яна Тревина к ответу Ричарда.

Ben Voigt 17.10.2014 23:16

Используя один из описанных выше методов, внутри конструктора атрибута вы можете указать исходное местоположение всего, что может иметь атрибут - например, класса. См. Следующий класс атрибута:

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):

Другие вопросы по теме