Есть ли способ получить ссылку на вызывающий объект в C #? - PullRequest
20 голосов
/ 07 января 2009

Что меня интересует, так это то, что можно (например) пройтись по кадрам стека, проверить каждый вызывающий объект на предмет соответствия интерфейса и, если да, извлечь некоторые данные из него.

Да, я знаю, что это плохая практика, мне интересно, возможно ли это.

Ответы [ 3 ]

20 голосов
/ 07 января 2009

Нет, по крайней мере, без использования API профилирования / отладки некоторого описания. Вы можете пройтись по стеку, чтобы найти вызывающий метод , с оговоркой, что он действительно медленный и может быть неточным из-за оптимизации JIT. Это не скажет вам, что является вызывающим объектом (если он действительно есть).

3 голосов
/ 07 января 2009

Если вы хотите получить тип, вы можете попробовать это:

новый StackFrame (1) .GetMethod (). DeclaringType

Как указал Джон, могут возникнуть проблемы, если вы столкнетесь с оптимизацией jit.

Что касается получения данных от объекта, я не думаю, что это возможно.

Редактировать

Просто, чтобы подробно остановиться на проблеме оптимизации, возьмите следующий код:

class stackTest
    {
        public void Test()
        {
            StackFrame sFrame = new StackFrame(1);
            if (sFrame == null)
            {
                Console.WriteLine("sFrame is null");
                return;
            }

            var method = sFrame.GetMethod();

            if (method == null)
            {
                Console.WriteLine("method is null");
                return;
            }
            Type declaringType = method.DeclaringType;
            Console.WriteLine(declaringType.Name);
        }

        public void Test2()
        {
            Console.WriteLine(new StackFrame(1).GetMethod().DeclaringType.Name);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            stackTest s = new stackTest();
            s.Test();
            Console.WriteLine("Doing Test2");
            s.Test2();
            Console.ReadLine();

        }
    }

Мы должны дважды загрузить Program на консоль, и когда вы запустите ее в отладчике, вы это сделаете. Когда вы работаете без отладчика в режиме выпуска, вы получаете вывод из первой функции Test. Что, вероятно, потому, что это сложно, чтобы быть встроенным; однако второй метод вызывает исключение нулевой ссылки.

Другая опасность, связанная с этим кодом, состоит в том, что в MS улучшается JIT-компилятор, который, возможно, работал в 2.0, мог привести к сбою и сбою в будущих версиях.

0 голосов
/ 07 января 2009

см. Этот вопрос:
Можете ли вы использовать отражение, чтобы найти имя выполняемого в данный момент метода?

Это не дубликат, но ответ на этот вопрос также ответит на ваш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...