Могу ли я получить вызывающий экземпляр из метода через рефлексию / диагностику? - PullRequest
12 голосов
/ 19 сентября 2008

Есть ли способ через System.Reflection, System.Diagnostics или другой получить ссылку на фактический экземпляр, который вызывает статический метод, не передавая его самому методу?

Например, что-то в этом роде

class A
{
    public void DoSomething()
    {
        StaticClass.ExecuteMethod();
    }
}

class B
{
    public void DoSomething()
    {
        SomeOtherClass.ExecuteMethod();
    }
}
public class SomeOtherClass
{
    public static void ExecuteMethod()
    {
        // Returns an instance of A if called from class A
        // or an instance of B if called from class B.
        object caller = getCallingInstance();
    }
}

Я могу получить тип, используя System.Diagnostics.StackTrace.GetFrames , но есть ли способ получить ссылку на фактический экземпляр?

Мне известны проблемы с отражением и производительностью, а также со статическими и статическими вызовами, и что это вообще, возможно, даже почти универсально, неправильный подход к этому. Часть причины этого вопроса - мне было любопытно, выполнимо ли это; в настоящее время мы передаем экземпляр в.

ExecuteMethod(instance)

И я просто подумал, возможно ли это, и все еще могу получить доступ к экземпляру.

ExecuteMethod()

@ Стив Купер: Я не рассматривал методы расширения. Некоторые варианты этого могут сработать.

Ответы [ 5 ]

10 голосов
/ 19 сентября 2008

Рассмотрите возможность сделать метод методом расширения. Определите это как:

public static StaticExecute(this object instance)
{
    // Reference to 'instance'
}

Это называется как:

this.StaticExecute();

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

Мне интересно, нужно ли просто передавать вызывающий объект в качестве правильного параметра. В конце концов, static - это подсказка, что этот метод не зависит ни от чего, кроме его входных параметров. Также обратите внимание, что этот метод может быть слишком сложным для тестирования, так как любой тестовый код, который вы пишете, не будет иметь тот же вызывающий объект, что и работающая система.

6 голосов
/ 19 сентября 2008

Я не верю, что ты можешь. Даже классы StackTrace и StackFrame просто предоставляют вам информацию об именах, а не доступ к экземплярам.

Я точно не знаю, почему вы хотите это сделать, но знаю, что даже если бы вы могли это сделать, это, вероятно, было бы очень медленно.

Лучшим решением было бы поместить экземпляр в локальный контекст потока перед вызовом ExecuteMethod, который вы можете извлечь из него или просто передать экземпляр.

1 голос
/ 19 сентября 2008

В случае статического метода, вызывающего ваш статический метод, нет вызывающего экземпляра.

Найдите другой способ выполнить то, что вы пытаетесь сделать.

1 голос
/ 19 сентября 2008

Просто заставьте ExecuteMethod взять объект. Тогда у вас есть экземпляр, несмотря ни на что.

0 голосов
/ 19 сентября 2008

Я чувствую, что что-то упустил здесь. Статический метод может быть вызван буквально из любого места. Нет никакой гарантии, что экземпляр класса A или класса B появится где-нибудь в стеке вызовов.

Должен быть лучший способ выполнить то, что вы пытаетесь сделать.

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