2012-06-30 12 views
5

Zauważyłem, że .NET 4.5 ma nowy atrybut o nazwie [CallerMemberNameAttribute], który po dołączeniu do parametru metody, poda nazwę ciągu znaków o nazwie tą metodą (jeśli ma to sens).C# Uzyskaj metodę wywoływania bez śledzenia stosu

Niestety, (ponieważ chcę coś zrobić z XNA) celuję tylko w .NET 4.0.

Chcę być w stanie zrobić coś takiego:

void MethodA() { 
    MethodB(); 
} 

void MethodB() { 
    string callingMethodName = (...?); 
    Console.WriteLine(callingMethodName); 
} 

Gdzie mój wynik byłby sposób A.

Wiem, że mógłbym to zrobić poprzez ślad stosu, ale to) zawodne i b) Sloooow ... Więc zastanawiam się, czy jest jakiś inny sposób, aby zebrać te informacje, które mogą być jednak ...

Miałem nadzieję na pomysły i wiedzę, które każdy może mieć w tej kwestii. Z góry dziękuję :)

+3

Należy podać nazwę metody wywołania jako ciąg znaków? – Oded

+2

@Dokładnie Tak, tak wyraźnie mogłem wywołać MethodB ("MethodA"), ale chodzi o to, że próbuję to zrobić dynamicznie, więc jeśli zmienię MethodA na MethodC, nie będę musiał edytować tego połączenia. – Xenoprimate

+0

Nie udało ci się przedstawić tego punktu w pytaniu. – Oded

Odpowiedz

13

Jeśli używasz Visual Studio 2012 do skompilowania tego, możesz napisać własną wersję CallerMemberNameAttribute i używać jej w taki sam sposób jak w .NET 4.5, nawet jeśli nadal kierujesz się na .NET 4.0 lub 3.5. Kompilator będzie nadal wykonywać zamianę w czasie kompilacji, nawet przy starszej wersji szkieletu.

Wystarczy dodanie następujących do projektu rade:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class CallerMemberNameAttribute : Attribute { } 
} 
+0

Jestem tylko programistą hobbystów, przepraszam, jeśli to głupie pytanie, ale czy jest sposób, w jaki mogę zobaczyć źródło dla Microsoft CallerMemberNameAttribute? Żeby to skopiować, mam na myśli. – Xenoprimate

+2

Ogólnie rzecz biorąc, tak, możesz dekompilować biblioteki .NET przy użyciu ILSpy. http://wiki.sharpdevelop.net/ILSpy.ashx Jednak atrybuty rzadko dają coś interesującego, ponieważ interesujący bit jest częściej wykorzystywany przez inny kod. Na przykład. z tego co mówi @ReedCopsey, transformacja jest wykonywana w czasie kompilacji przez kompilator, a nie przez sam atrybut, i nie potrzebujesz nawet środowiska wykonawczego .NET 4.5, więc prawdopodobnie nie zobaczysz interesującego kodu. –

+0

Ah, więc kompilator po prostu widzi nazwę "CallerMemberNameAttribute" i wstawia własną logikę?Jeśli tak, mogę po prostu utworzyć pusty atrybut o tej nazwie i to zadziała? – Xenoprimate

0

Można podać nazwę rozmówcy jako parametr do metody zwanej. Niekoniecznie co prosisz, ale działa bez konieczności dostępu do ramki stosu:

[MethodImpl(MethodImplOptions.NoInlining)] 
void MethodA() 
{ 
    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; 
    MethodB(methodName); 
} 

void MethodB(string callingMethodName) 
{ 
    Console.WriteLine(callingMethodName); 
} 

Korzystając MethodBase.GetCurrentMethod(), można zapewnić, że realizacja pozostaje Refactor bezpieczne - jeżeli nazwa firmy zmian sposobu, wyniki nadal będą poprawne.

Nie zapomnij oznaczyć swojej metody wywołania za pomocą MethodImplOptions.NoInlining, aby uniknąć inline.

Powiązane problemy