Определите тип вызывающего объекта в C#

    final String url = "some/url";

вместо:

    final JSONObject jsonBody = "{\"type\":\"example\"}";

вы можете использовать:

  JSONObject jsonBody = new JSONObject();
    try {
        jsonBody.put("type", "my type");
    } catch (JSONException e) {
        e.printStackTrace();
    }
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
14
задан DevinB 18 March 2009 в 17:10
поделиться

9 ответов

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

, Во-вторых, да, это возможно. Используйте System.Diagnostics.StackTrace для обхода стека; тогда получите соответствующее StackFrame, каждый выравнивает. Тогда определите, какой метод был вызывающей стороной при помощи GetMethod() на этом StackFrame. Обратите внимание, что создание отслеживания стека является потенциально дорогой операцией, и для вызывающих сторон Вашего метода возможно затенить, куда вещи действительно прибывают из.

<час>

Редактирование: Этот комментарий от OP делает это довольно ясным, что это могло, вероятно, быть универсальным или полиморфным методом. @devinb, Вы могли бы хотеть рассмотреть создание нового вопроса, который обеспечивает больше детали о том, что Вы пытаетесь сделать, и мы видим, предоставляет ли это себя хорошо хорошему решению.

короткая версия - то, что я закончил бы, имеют 30 или 40 идентичных функций, которые были просто выключены одной или двумя строками. †“devinb (12 secs назад)

17
ответ дан 1 December 2019 в 07:13
поделиться

Как альтернативный подход, имейте, Вы когда-либо считали предложение другим классом на основе типа объекта, который просит класс. Скажите следующий

public interface IC {
  int DoSomething();
}

public static CFactory { 
  public IC GetC(Type requestingType) { 
    if ( requestingType == typeof(BadType1) ) { 
      return new CForBadType1();
    } else if ( requestingType == typeof(OtherType) { 
      return new CForOtherType();
    }  
    ...
  }
}

, Это было бы намного более чистым подходом, чем имеют каждое изменение метода, это - поведение на основе вызывающего объекта. Это чисто выделило бы проблемы к различным реализациям IC. Кроме того, они могли все проксировать назад к реальной реализации C.

РЕДАКТИРОВАНИЕ Исследование стека вызовов

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

public class SomeBadObject {
  public void CallCIndirectly(C obj) { 
    var ret = Helper.CallDoSomething(c);
  }
}

public static class Helper {
  public int CallDoSomething(C obj) {
    return obj.DoSomething();
  }
}

Вы могли, конечно, идти далее назад на стеке вызовов. Но это еще более хрупко, потому что это может быть абсолютно легальный путь для SomeBadObject, чтобы быть на стеке когда различные вызовы объектов DoSomething.

13
ответ дан 1 December 2019 в 07:13
поделиться

Самый легкий ответ должен был бы передать в объекте отправителя как любое событие с типичным отправителем, eventargs методология.

Ваш код вызова был бы похож на это:

return c.DoSomething(input, this);

Ваш метод DoSomething просто проверил бы тип с помощью оператора IS:

public static int DoSomething(int input, object source)
{
    if(source is A)
        return input + 1;
    else if(source is B)
        return input + 2;
    else
        throw new ApplicationException();

}

Это походит на что-то с немного большим количеством ООП. Вы могли бы рассмотреть C, который абстрактный класс с методом, и имеющий A, B наследовал от C и просто называет метод. Это позволило бы Вам проверять тип базового объекта, который, очевидно, не имитируется.

Из любопытства, что Вы пробуете этой конструкцией?

2
ответ дан 1 December 2019 в 07:13
поделиться

Существует (почти) всегда надлежащий дизайн, который может выполнить то, в чем Вы нуждаетесь. Если Вы отходите на один шаг для описания то, что на самом деле необходимо сделать, я уверен, что Вы получите по крайней мере один хороший дизайн, который не требует, чтобы необходимо было обратиться к чему-то вроде этого.

0
ответ дан 1 December 2019 в 07:13
поделиться

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

Как насчет интерфейса, это A,B реализовало бы?

interface IFoo { 
     int Value { get; } 
}

И затем Ваш DoSomething метод был бы похож на это:

   public int DoSomething(int input, IFoo foo)
   {
        return input + foo.Value;
   }
0
ответ дан 1 December 2019 в 07:13
поделиться

Не надежно из-за возможности встраивания временем выполнения.

2
ответ дан 1 December 2019 в 07:13
поделиться

Вы могли исследовать стек вызовов, но это и дорого и хрупко. Когда Ваш код является jit'ed, компилятор мог бы встроить Ваши методы поэтому, в то время как он мог работать в режиме отладки, Вы могли получить другой стек при компиляции в режиме выпуска.

0
ответ дан 1 December 2019 в 07:13
поделиться

структурируйте его как обработчик событий, я уверен, что полицейский FX даже предложил бы, чтобы Вы сделали это

static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            throw new NotImplementedException();
        }
0
ответ дан 1 December 2019 в 07:13
поделиться

Вы могли использовать System.Diagnostics.StackTrace класс для создания отслеживания стека. Тогда Вы могли искать StackFrame, который связан с вызывающей стороной. Эти StackFrame имеет Method свойство, которое можно использовать для получения до типа вызывающей стороны.

Однако вышеупомянутый метод - ничто, что должно использоваться в производительности критический код.

0
ответ дан 1 December 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: