Есть ли способ получить ссылку на вызывающий объект в С#?
Мне интересно, возможно ли (например) подобрать кадры стека, проверить каждый вызывающий объект, чтобы увидеть, совпадает ли он с интерфейсом, и если так извлечь некоторые данные из него.
Да, я знаю, что это плохая практика, мне интересно, возможно ли это.
Ответы
Ответ 1
Нет, нет, по крайней мере, без использования API-интерфейса профилирования/отладки какого-либо описания. Вы можете пройти стек, чтобы найти метод вызова, с предостережением, что он действительно медленный и может быть неточным из-за оптимизаций JIT. Это не скажет вам, что такое вызывающий объект (если он действительно есть).
Ответ 2
Если вы хотите получить тип, вы можете попробовать следующее:
new 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();
}
}
Мы должны дважды запускать программу на консоль, а когда вы запускаете ее в отладчике. Когда вы запускаете без отладчика в режиме деблокирования, вы получаете выход из первой тестовой функции. Это, вероятно, потому, что сложно быть встроенным; однако второй метод вызывает исключение нулевой ссылки.
Другая опасность с этим кодом заключается в том, что при MS улучшает компилятор JIT, который мог бы работать в версии 2.0, может произойти сбой и сжечь в будущих версиях.
Ответ 3
Смотрите этот вопрос:
Можете ли вы использовать отражение, чтобы найти имя текущего исполняемого метода?
Это не дубликат, но ответ на этот вопрос также ответит на ваш вопрос.