2010-05-25 10 views
9

में से बर्ताव करता है तत्काल विंडो में निम्न का प्रयास करें:सी # == तत्काल विंडो में ऑपरेटर को अलग ढंग से चलाने के समय

object a1 = "a"; 
object a2 = "a"; 
a1==a2 // outputs false 

और आप देखेंगे कि a1 == a2 आउटपुट false

हालांकि, या तो एक खिड़की एप्लिकेशन या कंसोल में रनटाइम पर, आप true मिल जाएगा:

object t1 = "a"; 
object t2 = "a"; 
MessageBox.Show((t1 == t2).ToString()); // outputs true 

क्रम व्यवहार == ऑपरेटर और तार के लिए परिभाषा के अनुरूप है।

क्या किसी को पता है कि यह तत्काल खिड़की में एक बग है?

+0

+1 सिर्फ इसलिए कि मैंने कभी भी तत्काल खिड़की नहीं देखी है और यह साफ दिखता है! – RichK

उत्तर

15

जो आप वर्णन कर रहे हैं वह सही व्यवहार है।

== की परिभाषा Objectसंदर्भ इसकी तर्कों की तुलना करता है। यह == के कार्यान्वयन से String के कार्यान्वयन से अलग है जो स्ट्रिंग के मान की तुलना करता है। सी # में ऑपरेटर आभासी नहीं हैं। इसका मतलब है कि भले ही आपकी वस्तुएं वास्तव में तार हैं, क्योंकि स्थिर प्रकार objectObject से कहा जाता है, जिसका अर्थ है संदर्भ संदर्भ बनाया जाएगा।

सी # तारों में आंतरिक पूल में interned हो सकता है। आम तौर पर जब आप रनटाइम पर नए स्ट्रिंग बनाते हैं तो आपको पूरी तरह से नई स्ट्रिंग ऑब्जेक्ट का संदर्भ मिलता है। एक आंतरिक स्ट्रिंग प्राप्त करने के लिए आप string.Intern विधि को कॉल कर सकते हैं। हालांकि जब आप सी # कोड संकलित करते हैं, तो शाब्दिक तार स्वचालित रूप से आपके लिए प्रशिक्षित होते हैं, इसलिए यदि आपके कोड में दो स्थानों में एक ही शाब्दिक स्ट्रिंग है तो आपको उसी स्ट्रिंग ऑब्जेक्ट का संदर्भ मिलेगा।

तत्काल खिड़की में तारों को स्पष्ट रूप से प्रशिक्षित नहीं किया जाता है - हर बार नए तार बनाए जाते हैं, भले ही उनके पास समान मूल्य हो। लेकिन .NET में कोई आवश्यकता नहीं है कि सभी तारों को प्रशिक्षित किया जाना चाहिए, इसलिए मैं इसे एक बग नहीं मानता।

आपके कोड को इस बात पर भरोसा करना चाहिए कि तारों को प्रशिक्षित किया गया है या नहीं, क्योंकि यह कार्यान्वयन विस्तार है।

+3

बस ओपी के लिए चीजों को स्पष्ट करने के लिए: ऑपरेटर बहुरूपता में भाग नहीं लेते हैं, इसलिए उस मामले में यह '==' का 'ऑब्जेक्ट' कार्यान्वयन है जिसका उपयोग 'स्ट्रिंग' कार्यान्वयन नहीं है, इसलिए यह अप्रत्याशित व्यवहार है। –

+0

मैं "सही व्यवहार" कथन से सहमत नहीं हूं। तत्काल विंडो व्यवहार एमएसडीएन दस्तावेज़ीकरण के साथ और रन-टाइम के साथ संगत नहीं है, न ही जब आप ब्रेक पॉइंट डालते हैं और वास्तव में कोड में मौजूद चर का परीक्षण करते हैं। मुझे व्यक्तिगत रूप से लगता है कि माइक्रोसॉफ्ट को इसे ठीक करना चाहिए। –

+0

@ डैमियानो: आपका क्या मतलब है: "तत्काल विंडो व्यवहार संगत नहीं है .. जब आप ब्रेक पॉइंट डालते हैं और वास्तव में कोड में मौजूद चर का परीक्षण करते हैं।" क्या आप एक उदाहरण दे सकते हैं? "तत्काल विंडो व्यवहार एमएसडीएन दस्तावेज के अनुरूप नहीं है" प्रलेखन का आप किस विशिष्ट भाग का जिक्र कर रहे हैं? –

2

यह एक बग नहीं है; कारण यह है कि आपका रनटाइम कोड काम करता है क्योंकि उन तारों को इंटर्न किया जाता है (यानी, स्मृति में उन विशेष वर्ण अनुक्रमों का केवल एक ही प्रतिनिधित्व होता है। निरंतर "a" के प्रत्येक संदर्भ स्मृति में एक ही बिंदु को संदर्भित करता है)। तत्काल विंडो में, प्रत्येक के लिए एक नई स्ट्रिंग बनाई जाती है, इसलिए जब उनकी सामग्री समान होती है, तो वस्तुएं स्मृति में विभिन्न स्थानों पर इंगित करती हैं।

एक संदर्भ प्रकार पर == ऑपरेटर का उपयोग करते हुए एक संदर्भ तुलना करता है (जब तक वस्तु के रूप में विशिष्ट प्रकार संदर्भित किया जा रहा है, नहीं क्या वस्तु है, नहीं string --alters इस व्यवहार इस मामले में object --meaning है)। क्योंकि संकलित शाब्दिक तारों को प्रशिक्षित किया जाता है, उनके पास एक ही संदर्भ होता है। क्योंकि तत्काल खिड़की तार नए तार हैं, उनके पास एक ही संदर्भ नहीं है।

2

शायद रनटाइम पर संकलक स्ट्रिंग अक्षर को उसी संदर्भ स्थान पर इंगित करने के लिए अनुकूलित करेगा, लेकिन तत्काल विंडो में यह अनुकूलन नहीं होता है।

0

मैं सुझाव दूंगा कि यदि आप ऑप्टिमाइज़ेशन बंद कर देते हैं तो गैर-तत्काल संस्करण भी झूठी वापसी करेगा। जैसा कि कहा गया है, यह एक बग नहीं है, यह एक क्विर्क है जो संकलक के भीतर होता है लेकिन तत्काल खिड़की के भीतर नहीं होता है।