2010-10-30 9 views
5

StringBuilder.Capacity बिना अशक्त समाप्ति के संबंध नेट वर्णों की अधिकतम संख्या को सेट किए जाने चाहिए, है, या यह जब पी का उपयोग कर/आह्वान एक अशक्त टर्मिनेटर के लिए स्थान आरक्षित करने के लिए एक उच्च सेट होना चाहिए।पी/Invoke का उपयोग करते समय StringBuilder.Capacity सेट करने का सही तरीका क्या है?

प्राकृतिक प्रतिक्रिया यह एक उच्च सेट किया जाना चाहिए कि है, लेकिन यह पी/आह्वान की तरह लगता है स्वचालित रूप से क्षतिपूर्ति करने के लिए माना जाता है। असल में यह वास्तव में यहां दस्तावेज किया गया है: http://msdn.microsoft.com/en-US/library/s9ts558h(v=VS.100).aspx

इस प्रश्न का कारण यह है कि अधिकांश उदाहरण उपर्युक्त दस्तावेज़ीकरण के साथ सख्ती से संगत नहीं हैं। लगभग हमेशा वे कोडित रहे हैं:

StringBuilder sb = new StringBuilder(dotNetChars + 1); 
SomeWindowsAPI(sb, sb.Capacity); 

बजाय:

StringBuilder sb = new StringBuilder(dotNetChars); 
SomeWindowsAPI(sb, sb.Capacity + 1); 

(मुझे लगता है कि कुछ APIs बफर आकार पैरामीटर अलग ढंग से संभाल मान लें कि एपीआई इस जरूरी आम तरीका संभालती है, GetFullPathName की तरह।: http://msdn.microsoft.com/en-us/library/aa364963(v=VS.85).aspx)

एपीआई कॉल में सीधे sb.Capacity के साथ एक अभिव्यक्ति का उपयोग करना एक मेल खाने से बचने के लिए एक सर्वोत्तम अभ्यास प्रतीत होता है। मुद्दा यह है कि +1 जोड़ना सही है या नहीं।

चारों ओर देखो। आपको शायद पता चलेगा कि sb.Capacity + 1 दिखाए जाने वाला एकमात्र स्थान एमएसडीएन दस्तावेज है।

बेशक

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

उत्तर

0

StringBuilder के निर्माता के अंदर, क्षमता इस तरह प्रयोग किया जाता है:

m_ChunkChars = new char[capacity]; 

यह m_ChunkLength क्षेत्र के साथ एक साथ प्रयोग किया जाता है StringBuilder की सामग्री को निर्धारित करने के लिए। यह केवल वास्तविक वर्णों का वर्णन करता है, जिसमें एक समाप्ति चरित्र शामिल नहीं है।

तो आपका जवाब + 1 आवश्यक नहीं है।

+1

लेकिन पी/Invoke इस के साथ क्या करता है? यदि पी/Invoke केवल उस सरणी में पहले अक्षर के पते को बाहरी फ़ंक्शन पर पास करता है, तो शून्य शून्य टर्मिनेटर के लिए 1 छोटा है। –

+0

स्ट्रिंग्स को पिनवोक के लिए मार्शल किया गया है और '\ 0' जोड़ने जैसी चीजें ढांचे द्वारा स्वचालित रूप से की जाती हैं। मेरा मानना ​​है कि इस उदाहरण में, आपको इसे ध्यान में रखना नहीं है। –

0

शायद कार्गो पंथ प्रोग्रामिंग की एक निश्चित राशि चल रहा है। किसी ने आदत को उठाया, जब तारों के लिए आवंटित स्मृति के बारे में पूछा गया, लंबाई के बजाय "लंबाई + 1" का जवाब देने के लिए। नए परिस्थितियों के लिए प्रलेखन को पढ़ने के बजाय, जिसमें आपको तारों के लिए आवंटित करने के लिए स्मृति के बारे में पूछा जाता है, डेवलपर सिर्फ "सुरक्षित पक्ष पर गलती करता है" और लंबाई में गुजरता है। 1. जो कोड पढ़ते हैं वे एक ही नियम और अभ्यास का अनुमान लगाते हैं फैलता है। इसे व्यक्ति से व्यक्तिगत रूप से पारित करने का अधिकार नहीं होना चाहिए, उचित रूप से सही होने की संभावना है, और सक्रिय रूप से हानिकारक नहीं है।

2

मुझे एहसास है कि आपके पास पांच साल के पुराने जवाब हैं, लेकिन मेरी राय में वे वास्तव में सवाल का जवाब नहीं देते हैं, वे मूल रूप से संभावित समस्या को दूर किए बिना जांच कर सकते हैं कि ऐसा करना सही है या नहीं।

एमएसडीएन दस्तावेज गारंटी देता है कि मार्शलर यह सुनिश्चित करेगा कि StringBuilder और एक अतिरिक्त शून्य टर्मिनेटर के पूर्ण Capacity को स्टोर करने के लिए पर्याप्त जगह है।का हवाला देते हुए Default Marshaling for Strings:

निश्चित-लंबाई स्ट्रिंग बफ़र

[...]

समाधान एक स्ट्रिंग के बजाय तर्क के रूप में एक StringBuilder बफर पारित करने के लिए है। स्ट्रिंगबिल्डर को कैलिफ़िक द्वारा संदर्भित और संशोधित किया जा सकता है, बशर्ते यह स्ट्रिंगबिल्डर की क्षमता से अधिक न हो। इसे एक निश्चित लंबाई में भी शुरू किया जा सकता है। उदाहरण के लिए, यदि आप स्ट्रिंगबिल्डरएन की क्षमता के लिए बफर प्रारंभ करते हैं, तो मार्शलर आकार का एक बफर (एन +1) वर्ण प्रदान करता है। +1 इस तथ्य के लिए खाता है कि अप्रबंधित स्ट्रिंग में शून्य टर्मिनेटर है जबकि स्ट्रिंगबिल्डर नहीं है।

[...]

तो तुम क्षमता के लिए एक जोड़ने के बारे में चिंता करने की ज़रूरत नहीं है, marshaller आपके लिए यह कार्य पहले से ही होगा।

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

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