2015-12-16 11 views
5
.method public static void Test<class T>(object A_0) cil managed 
{ 
    // Code size  13 (0xd) 
    .maxstack 1 
    .locals init (!!T V_0) 
    IL_0000: ldarg.0 
    IL_0001: isinst  !!T 
    IL_0006: unbox.any !!T 
    IL_000b: stloc.0 
    IL_000c: ret 
} // end of method DemoType::Test 

बराबर सी # कोड है:सीआईएल unbox_any अनुदेश - अजीब व्यवहार

public static void Test<T>(object o) where T : class 
{ 
    T t = o as T; 
} 

मेरे प्रश्न हैं:

  1. क्यों unbox.any बुलाया गया? अगर आप सिर्फ

    कर
    var a = father as child 
    

    isinst intruction कॉल करेंगे और कोई unbox.any, और अगर मैं सामान्य परिभाषा को हटाने और करेंगे मैं, कुछ वर्ग के लिए (isinst) कास्ट करने के लिए वस्तु नहीं unbox.any कोशिश करता हूँ बुलाया जाएगा।

  2. शायद unbox.any को सामान्य परिभाषा कहा जाता है, इसलिए इस मामले में unbox.any को NullReferenceException फेंकने की आवश्यकता है क्योंकि इस कास्टिंग के लिए isinst निर्देश वापसी का उत्तर शून्य है। unbox_any देखें। और यदि आप इस कोड को चलाने का प्रयास करते हैं तो आप देखेंगे कि कोई अपवाद नहीं फेंक दिया गया है।

अद्यतन

मैं वस्तु प्रकार पैरामीटर क्योंकि unbox_any समझ सकते हैं और यह isinst जांच के बाद ठोस प्रकार में कास्ट करने के लिए प्रयास करें। शायद जेनेरिक प्रभाव भी।

मेरा सवाल है, क्यों नहीं unbox में अपवाद फेंक दिया। यदि ओबीजे हम टी को अनबॉक्स करने की कोशिश करते हैं तो शून्य है?

प्रलेखन कहता है: "ओब्ज एक शून्य संदर्भ है, तो NullReferenceException फेंक दिया जाता है।"

+0

क्या आप इतना अजीब बात कर सकते हैं? मेरे लिए यह समझ में आता है। बिंदु (2) में आपने एक प्रश्न नहीं पूछा है, या तो। – usr

+0

@usr पहले, मैं सत्यापित करना चाहता हूं कि क्यों unbox_any कहा जाता है। उन दोनों को बुलाए जाने की क्या भावना है? (isinst और unbox_any) दूसरा, और अधिक महत्वपूर्ण, अगर unbox_any को पास किया गया तो कोई अपवाद नहीं उठाया गया है? –

उत्तर

4

अनबॉक्स को सत्यापनकर्ता को खुश रखना है। सत्यापनकर्ता यह जानने के बारे में विशेष रूप से स्मार्ट नहीं है कि एक प्रकार पैरामीटर टी हमेशा एक संदर्भ प्रकार होने जा रहा है, और इसलिए सी # कंपाइलर इन अन्य अनावश्यक अनबॉक्सों को उत्सर्जित करता है।

यदि आप Unbox_any और IsVerifierReference के लिए Roslyn स्रोत कोड की खोज करते हैं तो आप देखेंगे कि कोड जनरेटर के आस-पास कुछ जगहों पर यह होता है।

जिटर को कोड उत्पन्न करते समय पता चलेगा कि टाइप पैरामीटर एक संदर्भ है या नहीं और प्रतीत होता है कि अनावश्यक निर्देशों के बावजूद सभ्य कोड उत्पन्न करना चाहिए।

+1

यदि कोई इसमें रूचि रखता है तो मैं पूरी तस्वीर के लिए [यहां] (http://stackoverflow.com/questions/34382683/jitter-logic-to-remove-unbox-any?lq=1) देखने की अनुशंसा करता हूं –

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