Могу ли я получить вызывающий экземпляр изнутри метода с помощью отражения / диагностики?

StackOverflow https://stackoverflow.com/questions/97193

  •  01-07-2019
  •  | 
  •  

Вопрос

Есть ли способ через 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();
    }
}

Я могу получить тип, используя Система.Диагностика.Отслеживание стека.Получение фреймов, но есть ли способ получить ссылку на фактический экземпляр?

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

ExecuteMethod(instance)

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

ExecuteMethod()

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

Это было полезно?

Решение

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

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

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

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

Подумайте о том, чтобы сделать этот метод методом расширения.Определите это как:

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

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

this.StaticExecute();

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top