2013-04-03 2 views
4

Мой код:Возможно ли в C# знать, кто вызвал статическое свойство/accessor?

public class CLASS_A {  

public static Dictionary<int, CLASS_A> List = new Dictionary<int, CLASS_A>; 
public static PP_CLASS pp = null; 

public static CLASS_A ID 
{ 
    get 
    { 
    int key = get_threadID; 
    if (List.ContainsKey(key)) 
    return List[key]; 
    else 
    return null; 
    } 
    set 
    { 
    int key = get_threadID; 
    List[key] = value; 
    } 
    } 

    public virtual void init(lib, name) 
    { 
    ... 
    if (name != "") 
    { 
     if (pp == null) 
     PP = this; 
    } 
    ... 
    } 
} 

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

45 = CLASS_A_object0 
67 = CLASS_A_object1 
... 

Но теперь, когда другой поток вызывает метод на стр, скажет CLASS_A.pp.setWelcome, это вернет нуль рра, и бросает исключение нулевого! Потому что когда set называется, идентификатор потока будет другим и не будет в списке.

Возможно ли, что я знаю, какой объект называется так, чтобы я мог делать обратный поиск? Или, может быть, другое решение?

Зачем мне это нужно: Первоначально мы подключались к одному устройству, чтобы это было нормально. Теперь есть несколько устройств, каждый из которых имеет свой собственный ip/port. Первоначальный код имел только public static PP_CLASS pp = null; Так что другие будут просто вызывать методы на pp, используя имя класса, и все было хорошо.

Предыдущее поведение: Программное обеспечение выбирает список устройств из файла, а так как pp статично, он разговаривает только с первым устройством. Я добавил, что строка pp==null, которую я забыл в своем первом сообщении. Поэтому при запуске кода pp==null будет истинным, а первое устройство будет назначено, но теперь для других устройств pp==null будет ложным, и поэтому я не могу разговаривать с другими устройствами.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

+0

Вы можете изменить свойство метода и добавить аргумент для «вызывающего абонента»? Затем просто выполните все ошибки, которые компилятор бросает на вас. – MrMoDoJoJr

+2

Из вашего вопроса неясно, что вы хотите, если один поток вызывает 'init', а другой поток пытается использовать' pp'. –

+0

Расскажите нам еще о вашем прецеденте. Почему вы хотите сохранить свои объекты с помощью потока в качестве ключа? У вас не будет отдельного экземпляра PP для потока, у вас будет общий PP для всех потоков после вызова PP. Это не имеет особого смысла, поскольку это означает, что PP и ваше свойство ID не имеют никаких отношений. Мне интересно, если вы ищете ThreadStatic: http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx. Кроме того - использование List в качестве идентификатора не очень хорошо. – SamStephens

ответ

1

, начинающееся с C# 5.0 (август 2012) есть новая функция "Caller Info Attribute". Если ваши классы хранятся в отдельных файлах, вы можете использовать CallerFilePathAttribute, чтобы зарегистрировать класс, который действительно вызвал.

Пример из MSDN:

// using System.Runtime.CompilerServices 
// using System.Diagnostics; 

public void DoProcessing() 
{ 
    TraceMessage("Something happened."); 
} 

public void TraceMessage(string message, 
     [CallerMemberName] string memberName = "", 
     [CallerFilePath] string sourceFilePath = "", 
     [CallerLineNumber] int sourceLineNumber = 0) 
{ 
    Trace.WriteLine("message: " + message); 
    Trace.WriteLine("member name: " + memberName); 
    Trace.WriteLine("source file path: " + sourceFilePath); 
    Trace.WriteLine("source line number: " + sourceLineNumber); 
} 

// Sample Output: 
// message: Something happened. 
// member name: DoProcessing 
// source file path: c:\Users\username\Documents\Visual Studio 2012\Projects\CallerInfoCS\CallerInfoCS\Form1.cs 
// source line number: 31 
+0

этот интересный. (всегда использовал stacktrace в прошлом, это выглядит проще) – Offler

0

Вы можете попробовать изучить трассировку стека.

var trace = new System.Diagnostics.StackTrace(); 

или получить вызывающую линию только это должно быть что-то вроде:

var caller = new System.Diagnostics.StackTrace().GetFrame(1) 
Смежные вопросы