मैं .NET के शुरुआती दिनों से स्पष्ट रूप से याद करता हूं जो स्ट्रिंगबिल्डर द्वारा उपयोग किए जाने वाले आंतरिक चार बफर के साथ नई स्ट्रिंग ऑब्जेक्ट (लौटाया जाना) प्रदान करने के लिए प्रयुक्त होता है। इस तरह यदि आपने स्ट्रिंगबिल्डर का उपयोग करके एक विशाल स्ट्रिंग का निर्माण किया है, तो ToString को कॉल करने की आवश्यकता नहीं है।क्या स्ट्रिंगबिल्डर टूस्टिंग को कॉल करने के बाद अपरिवर्तनीय हो जाता है?
ऐसा करने में, स्ट्रिंगबिल्डर को बफर में किसी भी अतिरिक्त परिवर्तन को रोकना पड़ा, क्योंकि अब इसे एक अपरिवर्तनीय स्ट्रिंग द्वारा उपयोग किया गया था। नतीजतन, स्ट्रिंगबिल्डर एक "कॉपी-ऑन-चेंज" पर स्विच करेगा जहां कोई भी प्रयास किया गया परिवर्तन पहले एक नया बफर बनायेगा, पुराने बफर की सामग्री को कॉपी करें और केवल तभी इसे बदलें।
मुझे लगता है कि धारणा यह थी कि स्ट्रिंगबिल्डर का उपयोग स्ट्रिंग बनाने के लिए किया जाएगा, फिर नियमित स्ट्रिंग में परिवर्तित किया जाएगा और त्याग दिया जाएगा। मुझे एक उचित धारणा की तरह लगता है।
अब यह बात है। मुझे दस्तावेज़ीकरण में इसका कोई उल्लेख नहीं मिल रहा है। लेकिन मुझे यकीन नहीं है कि यह कभी दस्तावेज किया गया था।
तो मैं परावर्तक (.NET 4.0) का उपयोग कर ToString के कार्यान्वयन को देखा है, और मुझे लगता है कि यह वास्तव में प्रतियां स्ट्रिंग, बस बफर का हिस्सा बजाय: अब
[SecuritySafeCritical]
public override unsafe string ToString()
{
string str = string.FastAllocateString(this.Length);
StringBuilder chunkPrevious = this;
fixed (char* str2 = ((char*) str))
{
char* chPtr = str2;
do
{
if (chunkPrevious.m_ChunkLength > 0)
{
char[] chunkChars = chunkPrevious.m_ChunkChars;
int chunkOffset = chunkPrevious.m_ChunkOffset;
int chunkLength = chunkPrevious.m_ChunkLength;
if ((((ulong) (chunkLength + chunkOffset)) > str.Length) || (chunkLength > chunkChars.Length))
{
throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
fixed (char* chRef = chunkChars)
{
string.wstrcpy(chPtr + chunkOffset, chRef, chunkLength);
}
}
chunkPrevious = chunkPrevious.m_ChunkPrevious;
}
while (chunkPrevious != null);
}
return str;
}
, जैसा कि मैंने इससे पहले कि मैं स्पष्ट रूप से पढ़ना याद रखूं कि शुरुआती दिनों में यह मामला था। नेट। मुझे इस book में भी उल्लेख किया गया।
मेरा सवाल है, क्या यह व्यवहार गिरा दिया गया था? यदि हां, तो कोई जानता है क्यों? यह मेरे लिए सही मायने रखता है ...
दिलचस्प। स्ट्रिंग को char [] s की श्रृंखला के रूप में संग्रहीत किया जाता है। लेकिन रेखा "chunkPrevious = chunkPrevious.m_Chunk पूर्व नहीं है;" मतलब है कि उन सरणी स्ट्रिंगबिल्डर के अलग-अलग उदाहरणों में संग्रहीत हैं, जो एक लिंक-सूची के रूप में संबंधित हैं, आंतरिक रूप से स्ट्रिंगबिल्डर के उदाहरण में हमारे पास संदर्भ है? – Sorax