2012-01-18 15 views
6

के रूप में 0 के साथ एक निजी स्थिर विधि तक पहुँचने मुझे यकीन है कि अगर मैं इस यहाँ पूछना चाहिए नहीं कर रहा हूँ, लेकिन यहाँ हम चले, यूनिट एक निजी स्थिर विधि एक छोटी मैं केवल जब यह एक MissingMethodException हो रही है पैरामीटर के रूप में है कि परीक्षण करते हुए पैरामीटर 0.क्या यह एक बग है? MissingMethodException पैरामीटर

मैं वी.एस. उपयोग कर रहा हूँ 2010 SP1 फ्रेमवर्क 4 (पूर्ण), यहाँ इस त्रुटि पुन: पेश करने न्यूनतम कोड है लक्ष्य (हम एक VB6 कोड उन्नयन कर रहे हैं तो अशिष्ट होना नहीं है) है:

PrivateType privateHelperType = new PrivateType(typeof(NotificationContext)); 
     var actual = (NotificationResult)privateHelperType.InvokeStatic(
     "GetExecuteResult", (short)1); 
     var actual2 = (NotificationResult)privateHelperType.InvokeStatic(
     "GetExecuteResult", (short)0); //here is where i get the exception 
:
[DataContract] 
    public enum NotificationResult 
    { 
    [EnumMember] 
    Success, 
    [EnumMember] 
    StoredError, 
    [EnumMember] 
    InvalidId, 
    [EnumMember] 
    OperationError, 
    } 

    public sealed class NotificationContext 
    { 
    private static NotificationResult GetExecuteResult(short result) 
    { 
     NotificationResult executeResult; 
     switch (result) 
     { 
     case 0: 
      executeResult = NotificationResult.Success; 
      break; 
     case 1: 
      executeResult = NotificationResult.StoredError; 
      break; 
     case 2: 
      executeResult = NotificationResult.InvalidId; 
      break; 
     default: 
      executeResult = NotificationResult.OperationError; 
      break; 
     } 

     return executeResult; 
    } 
    } 

यहाँ कैसे मैं कोड का परीक्षण कर रहा हूँ है

पहले मंगलाचरण मैं उम्मीद परिणाम प्राप्त में, दूसरे मंगलाचरण में मैं अपवाद (मैं कम सोच है कि शायद अपवाद है क्योंकि यह एक पैरामीटर के रूप में एक पूर्णांक के साथ एक विधि नहीं मिल रहा था करने के लिए डाली जोड़ा) मिलता है।

व्यवहार प्रजनन करने में सक्षम किसी को भी है ?, मैंने कुछ गलत कर रहा हूँ?

आपकी मदद के लिए धन्यवाद।

+0

निजी तरीकों का परीक्षण न करें। – jason

+1

@ जेसन मुझे पता है, लेकिन जैसा कि मैंने कहा, हम एक वीबी 6 ऐप को अपग्रेड कर रहे हैं और इस विधि को 100% कवरेज नहीं मिल रहा था और हमें इसे सत्यापित करने के लिए इसे सत्यापित करने की आवश्यकता है। –

+0

आपको अपने निजी तरीकों पर 100% कवरेज की आवश्यकता नहीं है; केवल आपके गैर-निजी तरीकों। – jason

उत्तर

8

समस्या इस विधि के दो भार के देखते हैं कि है (वहाँ दूसरों रहे हैं, लेकिन उन्होंने इस मामले यहाँ नहीं है):

अंतर यह है कि दूसरे अधिभार में BindingFlags प्रकार का पैरामीटर है, जो enum है। और जब तुम दूसरा पैरामीटर के रूप में शाब्दिक 0 गुजरती हैं, इस अधिभार चुना जाता है, क्योंकि शाब्दिक 0 परोक्ष किसी भी enum और नहीं params का उपयोग कर के लिए परिवर्तनीय अधिभार संकल्प में इसका उपयोग करने की तुलना में बेहतर समझा जाता है। तो, मूल रूप से

  • privateType.InvokeStatic("GetExecuteResult", 1)privateType.InvokeStatic("GetExecuteResult", new object[] { 1 })
  • privateType.InvokeStatic("GetExecuteResult", 0) में संकलित किया गया है privateType.InvokeStatic("GetExecuteResult", 0, new object[] { })

में संकलित किया गया है यह आपकी समस्या का कारण है। मैं स्पष्ट तरीका यह स्पष्ट रूप से सरणी बनाने के लिए किया जाएगा से बचने के लिए लगता है:

privateType.InvokeStatic("GetExecuteResult", new object[] { 0 }) 

अपने कोड में छोड़कर आप विधि के लिए शाब्दिक 0 उत्तीर्ण नहीं होते हैं, तो आप इसे पहले डाली। विनिर्देश के अनुसार, BindingFlags अधिभार इस मामले में नहीं चुना जाना चाहिए।लेकिन errors like this are a known bug, जो तय नहीं किया जाएगा, क्योंकि यह कुछ कामकाजी कार्यक्रमों को तोड़ देगा।

+0

मेरा मानना ​​है कि आप जो बग खोज रहे हैं वह यह है कि मूल रूप से प्रश्न में व्यक्त किए गए 0 स्थिर (यहां तक ​​कि कलाकारों के साथ) भी enum अधिभार में जाता है। [यह] देखें (http://stackoverflow.com/questions/2043554/method-overload-resolution-unexpected- व्यवहार), जो [इस] को इंगित करता है (http://blogs.msdn.com/ericlippert/archive/2006 /03/29/the-root-of-all-evil-part-two.aspx)। –

+0

@ एंथनी पेगम, एरिक लिपर्ट का वह लेख वह है जिसे मैं सोच रहा था। मैंने जवाब में इसका एक लिंक जोड़ा है। – svick

+0

आप सही हैं, उत्तर के रूप में चिह्नित किया गया है क्योंकि अधिक पूर्ण है –

-3

मैं आपकी कक्षा को सील नहीं करने का प्रयास करूंगा। यह पूरी तरह से अनुमान है लेकिन हो सकता है कि यह आपके नोटिफिकेशन कॉन्टेक्स्ट को निजी टाइप के हिस्से के रूप में उप-वर्गीकृत कर रहा हो। http://blogs.jetbrains.com/dotnet/2011/05/free-net-decompiler-is-available-for-early-access/ क्या PrivateType तरह लग रहा है पर एक नजर है करने के लिए:

मेरी दूसरी सिफारिश dotpeek की तरह कुछ डाउनलोड करने के लिए है। यह समझना कि यह कैसे काम करता है वास्तव में क्या हो रहा है यह जानने में मदद करेगा।

+1

एक स्टेक विधि का आह्वान करते समय 'मुहरबंद' क्यों होगा? – svick

+0

हाँ अच्छा बिंदु, मस्तिष्क फीका है ... अभी भी स्रोत का निरीक्षण करना एक अच्छी शुरुआत है। – Dessus

3

दिलचस्प ... मैं इसे पुन: पेश करने में सक्षम था, और मैं इसे ठीक करने के लिए एक रास्ता मिल गया।

short s = 0; 
var actual2 = (NotificationResult)privateHelperType.InvokeStatic(
     "GetExecuteResult", s); 
+0

मजाकिया, मैंने कभी कोशिश नहीं की क्योंकि मैं अपने सभी स्थिरांक के साथ एक आंतरिक स्थैतिक वर्ग का उपयोग कर रहा था, मेरी कक्षा में मेरे पास "आंतरिक कॉन्स लघु सफलता = 0;" थी और अभी भी त्रुटि हो रही है। –

+0

मुझे लगता है कि ऐसा इसलिए है क्योंकि पैरामीटर का प्रकार ऑब्जेक्ट है। जब आप इसे कास्ट करते हैं, तो यह ऑब्जेक्ट के उदाहरण के प्रकार को नहीं बदलता है। यह ऑब्जेक्ट के उदाहरण को उस प्रकार के चर द्वारा संदर्भित करने की अनुमति देता है। जब आप उस ऑब्जेक्ट को पास करते हैं जिसे आप संदर्भित करते हैं तो int16 के प्रकार की स्मृति में एक मान। –

संबंधित मुद्दे