2009-03-05 10 views
46

संभव डुप्लिकेट:
How can I find the method that called the current method?एक विधि के भीतर से बुला विधि नाम प्राप्त कर रहा है

मैं एक उद्देश्य यह है कि वस्तु के भीतर स्थानों के एक नंबर से कहा जाता है में एक विधि है। क्या इस लोकप्रिय विधि को बुलाए जाने वाले विधि का नाम पाने का एक तेज़ और आसान तरीका है।

छद्म कोड उदाहरण:

public Main() 
{ 
    PopularMethod(); 
} 

public ButtonClick(object sender, EventArgs e) 
{ 
    PopularMethod(); 
} 

public Button2Click(object sender, EventArgs e) 
{ 
    PopularMethod(); 
} 

public void PopularMethod() 
{ 
    //Get calling method name 
} 

PopularMethod() के भीतर मैं Main का मूल्य देखना चाहेंगे अगर यह Main से बुलाया गया था ... मैं देखने के लिए "ButtonClick" अगर PopularMethod()ButtonClick से बुलाया गया था चाहते हैं

मैं System.Reflection.MethodBase.GetCurrentMethod() पर देख रहा था लेकिन मुझे कॉलिंग विधि नहीं मिलेगी। मैंने StackTrace कक्षा को देखा है, लेकिन जब भी विधि कहा जाता है तो मुझे वास्तव में एक संपूर्ण स्टैक ट्रेस चलाने से प्रसन्नता नहीं होती।

उत्तर

67

मुझे नहीं लगता कि यह ढेर लगाने के बिना किया जा सकता है:

[System.Runtime.CompilerServices.MethodImpl(
System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] 
public void PopularMethod() 
{ 
    var currentMethod = System.Reflection.MethodInfo 
     .GetCurrentMethod(); 
} 

बुला विधि प्राप्त करने के लिए।

StackTrace stackTrace = new StackTrace(); 
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod(); 
Console.WriteLine(methodBase.Name); // e.g. 

हालांकि, मुझे लगता है कि तुम सच में बंद करो और अपने आप से पूछना अगर यह आवश्यक है करने के लिए है: हालांकि, यह है कि ऐसा करने के लिए काफी सरल है।

+0

अधिक जानकारी के लिए देखें: http://discuss.joelonsoftware.com/default.asp?dotnet.12.511358.10 –

+3

सिस्टम। डायग्नोस्टिक्स स्टैकट्रेस, सिस्टम का नामस्थान है। प्रतिबिंब विधिबेस का नामस्थान है। – Guvante

+0

जेसन - धन्यवाद, मुझे यकीन नहीं है कि "स्टैकट्रेस" विधि कितनी संसाधन गहन है, लेकिन यह मुझे वह चीज़ मिलती है जो मैं ढूंढ रहा हूं। यह सिर्फ मेरे लिए एक डीबगिंग कोड ब्लॉक है, यह उत्पादन में नहीं जा रहा है। आपकी मदद के लिए पुनः शुक्रिया ! –

16

यह वास्तव में वास्तव में सरल है।

public void PopularMethod() 
{ 
    var currentMethod = System.Reflection.MethodInfo 
     .GetCurrentMethod(); // as MethodBase 
} 

लेकिन सावधान रहें, अगर इस विधि को रेखांकित करने पर कोई संदेह है तो मुझे थोड़ा संदेह है। आप यह सुनिश्चित करने के लिए ऐसा कर सकते हैं कि जेआईटी कंपाइलर रास्ते में नहीं मिलेगा।

[System.Runtime.CompilerServices.MethodImpl(
System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] 
public void PopularMethod() 
{ 
    // 1 == skip frames, false = no file info 
    var callingMethod = new System.Diagnostics.StackTrace(1, false) 
     .GetFrame(0).GetMethod(); 
} 
+3

जॉन लीडग्रेन - इससे मुझे "PopularMethod" नाम मिलेगा, लेकिन मुझे उस विधि का नाम चाहिए जिसे PopularMethod कहा जाता है। –

+1

ठीक है, अच्छी तरह से स्टैक ट्रेस वह है जो आपको चाहिए। मैंने आपके प्रश्न को गलत तरीके से पढ़ाया। –

+0

बस इसके बजाय .GetFrame (1) का उपयोग करें, है ना? 'MethodInlining.NoInlining' के लिए –

5

बस एक पैरामीटर

public void PopularMethod(object sender) 
{ 

} 

IMO में पारित: यदि यह घटनाओं के लिए काफी अच्छा है यह इस बात के लिए काफी अच्छा होना चाहिए।

+0

Sruly - हाँ यह निश्चित रूप से एक विकल्प है, मैं विधि कॉल को बदलने के बिना इसे करने की कोशिश कर रहा था। यह मेरा आखिरी उपाय विकल्प होगा। –

+0

जब तक आप इसे सार्वजनिक एपीआई के रूप में उजागर नहीं कर लेते हैं, तो आप परेशानी से गुजरेंगे और प्रतिबिंब का उपयोग क्यों करेंगे यदि आप इसे इस तरह से कर सकते हैं? KISS – Sruly

+0

याद रखें यह सबसे अच्छा जवाब है, प्रतिबिंब या अन्य सामान का उपयोग न करें, कॉलर को पैरामीटर के माध्यम से आईडी करें। –

0

मुझे लगता है कि आपको अगले फ्रेम पर StackTrace कक्षा और फिर StackFrame.GetMethod() का उपयोग करने की आवश्यकता है।

हालांकि यह Reflection का उपयोग करने के लिए एक अजीब चीज की तरह लगता है। यदि आप PopularMethod को परिभाषित कर रहे हैं, तो आप जिस सूचना को वास्तव में चाहते हैं उसे पास करने के लिए पैरामीटर या कुछ परिभाषित नहीं कर सकते हैं। (या बेस क्लास या कुछ पर डालें ...)

1

जबकि आप सबसे निश्चित रूप से स्टैक का पता लगा सकते हैं और इसे इस तरह से समझ सकते हैं, तो मैं आपको अपने डिजाइन पर पुनर्विचार करने का आग्रह करता हूं। अगर आपकी विधि को किसी प्रकार के "राज्य" के बारे में जानने की ज़रूरत है, तो मैं कहूंगा कि केवल एक enum या कुछ बनाएं, और इसे अपने लोकप्रिय मोड() पर पैरामीटर के रूप में लें। उन पंक्तियों के साथ कुछ। आप जो पोस्ट कर रहे हैं उसके आधार पर, स्टैक का पता लगाने से आईएमओ अधिक हो जाएगा।

4

मुझे अक्सर यह करने की इच्छा है कि मैं स्वयं ऐसा करना चाहता हूं, लेकिन हमेशा मेरे सिस्टम के डिज़ाइन को दोबारा सुधारना समाप्त कर रहा हूं, इसलिए मुझे यह "कुत्ते को कुचलने वाला पूंछ" विरोधी पैटर्न नहीं मिलता है। नतीजा हमेशा एक और मजबूत वास्तुकला रहा है।

+0

क्या यह एक उत्तर है? –

104

.NET 4.5 में/सी # 5, इस सरल है:

public void PopularMethod([CallerMemberName] string caller = null) 
{ 
    // look at caller 
} 

संकलक फोन करने वाले का नाम स्वचालित रूप से कहते हैं, इसलिए:

void Foo() { 
    PopularMethod(); 
} 

"Foo" में पास हो जाएगा।

+0

उत्कृष्ट समाधान !! तब तक इंतजार नहीं कर सकता जब तक हम यहां 4.5 में परिवर्तित नहीं हो जाते (यह थोड़ी देर हो जाएगा) लेकिन मैं निश्चित रूप से इसे ध्यान में रखूंगा! धन्यवाद! –

+1

इस समाधान के प्रदर्शन परिणाम क्या हैं? – Feckmore

+3

@ फेकमोर कोई भी नहीं: संकलक इसे संकलन के दौरान एक शाब्दिक के रूप में जोड़ता है। यह स्टैकट्रेस इत्यादि जैसी किसी भी चीज़ की तुलना में तेजी से तेज़ होगा।मूल रूप से इसे लोकप्रिय मोड ("CurrentMethodName") के रूप में संकलित किया जाता है –