C # में एक उत्परिवर्तनीय और अपरिवर्तनीय स्ट्रिंग के बीच अंतर क्या है?


190

C # में एक उत्परिवर्तनीय और अपरिवर्तनीय स्ट्रिंग के बीच अंतर क्या है?



6
यह समान नहीं है। बहुत समान है, लेकिन यह समान के समान नहीं है।
मार्सेलो कैंटोस

जवाबों:


313

म्यूटेबल और अपरिवर्तनीय अंग्रेजी शब्द हैं जिनका अर्थ है "क्रमशः बदल सकते हैं" और "बदल नहीं सकते"। शब्दों का अर्थ आईटी संदर्भ में समान है; अर्थात

  • एक परिवर्तनशील स्ट्रिंग को बदला जा सकता है, और
  • एक अपरिवर्तनीय स्ट्रिंग को बदला नहीं जा सकता।

इन शब्दों के अर्थ C # / .NET में अन्य प्रोग्रामिंग भाषाओं / वातावरणों में समान हैं, हालांकि (जाहिर है) प्रकार के नाम भिन्न हो सकते हैं, जैसा कि अन्य विवरण हो सकता है।


रिकार्ड के लिए:

  • String मानक C # / .Net अपरिवर्तनीय स्ट्रिंग प्रकार है
  • StringBuilder मानक C # / .Net उत्परिवर्ती स्ट्रिंग प्रकार है

सी # के रूप में दर्शाए गए एक स्ट्रिंग पर "एक परिवर्तन को प्रभावित करने के लिए" String, आप वास्तव में एक नई Stringवस्तु बनाते हैं । मूल Stringनहीं बदला गया है ... क्योंकि यह अपरिवर्तनीय है।

ज्यादातर मामलों में इसका उपयोग करना बेहतर है Stringक्योंकि यह उनके बारे में आसान कारण है; उदाहरण के लिए आपको इस संभावना पर विचार करने की आवश्यकता नहीं है कि कुछ अन्य धागे "मेरी स्ट्रिंग बदल सकते हैं"। हालाँकि, जब आपको ऑपरेशन के अनुक्रम का उपयोग करके स्ट्रिंग बनाने या संशोधित करने की आवश्यकता होती है, तो यह ए का उपयोग करने के लिए अधिक कुशल हो सकता है StringBuilder


और अंत में, उन लोगों के लिए जो दावा करते हैं कि StringBuilderयह एक स्ट्रिंग नहीं है क्योंकि यह अपरिवर्तनीय नहीं है, Microsoft प्रलेखनStringBuilder इस प्रकार वर्णन करता है :

" वर्णों के एक परिवर्तनशील स्ट्रिंग का प्रतिनिधित्व करता है । इस वर्ग को विरासत में नहीं मिला है।"


182

String अपरिवर्तनीय है

यानी तार को बदला नहीं जा सकता। जब आप एक स्ट्रिंग बदलते हैं (उदाहरण के लिए इसे जोड़कर), तो आप वास्तव में एक नया स्ट्रिंग बना रहे हैं।

लेकिन StringBuilderअपरिवर्तनीय नहीं है (बल्कि, यह परस्पर है)

इसलिए यदि आपको कई बार स्ट्रिंग को बदलना पड़ता है, जैसे कि कई कॉन्टैक्शंस StringBuilder


4
यदि आप अपरिवर्तनीय तार को कई बार छुपाते हैं तो क्या होता है? संदर्भ के बिना तार के लिए मेमोरी उपयोग के भार? या बस धीमी गति से?
रुडी

13
@ रूडी - दोनों। प्रत्येक संयोजन एक नया स्ट्रिंग ऑब्जेक्ट बनाता है, और सभी इनपुट स्ट्रिंग्स के सभी वर्णों की प्रतिलिपि बनाता है। O(N^2)व्यवहार की ओर जाता है ...
स्टीफन सी

@StephenC ने कीवर्ड के साथ समझाया।
कैंट लियाउ जूल

6
अगर आपको एक स्ट्रिंग को कई बार बदलना है, जैसे कि कई कॉन्टेनेटेशन, तो स्ट्रिंगबर्ल का उपयोग करें ...
जिससे

45

एक वस्तु परस्पर परिवर्तनशील होती है, यदि एक बार बनाया गया, तो उस पर विभिन्न प्रचालनों को बुलाकर इसकी स्थिति को बदला जा सकता है, अन्यथा यह अपरिवर्तनीय है।

अपरिवर्तनीय स्ट्रिंग

C # (और .NET में) एक स्ट्रिंग को क्लास System.String द्वारा दर्शाया गया है। stringकीवर्ड इस वर्ग के लिए एक उपनाम है।

System.String वर्ग अपरिवर्तनीय है, यानी एक बार अपने राज्य परिवर्तित नहीं किया जा सकता है बनाया

सभी कार्यों को तो तुम एक स्ट्रिंग पर प्रदर्शन की तरह Substring, Remove,Replace , संयोजन का उपयोग कर '+' ऑपरेटर आदि एक नया स्ट्रिंग बनाने और इसे वापस आ जाएगी।

प्रदर्शन के लिए निम्नलिखित कार्यक्रम देखें -

string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);

यह क्रमशः 'स्ट्रिंग ’और ring मिस्ट्रिंग’ छापेगा।

अपरिवर्तनीयता के लाभों के लिए और स्ट्रिंग की अपरिवर्तनीय जाँच क्यों होती है। .NET स्ट्रिंग अपरिवर्तनीय क्यों है?

म्यूटेबल स्ट्रिंग

यदि आप एक स्ट्रिंग रखना चाहते हैं जिसे आप संशोधित करना चाहते हैं तो आप StringBuilderकक्षा का उपयोग कर सकते हैं । एक StringBuilder उदाहरण पर संचालन एक ही वस्तु को संशोधित करेगा

का उपयोग StringBuilder करने के लिए कब करें पर अधिक सलाह के लिए जब StringBuilder का उपयोग करने के लिए देखें ?


सुंदर व्याख्या!
हरि

36

सभी stringवस्तुएँ C # में अपरिवर्तनीय हैं। कक्षा की वस्तुएँ string, एक बार निर्मित होने के बाद, उनके द्वारा बनाए गए के अलावा किसी भी मूल्य का प्रतिनिधित्व नहीं कर सकती हैं। सभी ऑपरेशन जो एक स्ट्रिंग को "बदलने" के लिए प्रतीत होते हैं, एक नया निर्माण करते हैं। यह स्मृति के साथ अक्षम है, लेकिन यह विश्वास करने में सक्षम होने के संबंध में बेहद उपयोगी है कि एक स्ट्रिंग आपके तहत फॉर्म नहीं बदलेगी- क्योंकि जब तक आप अपना संदर्भ नहीं बदलते हैं, तब तक संदर्भित स्ट्रिंग को कभी नहीं बदलेगा।

इसके विपरीत, एक परिवर्तनशील वस्तु में डेटा फ़ील्ड होते हैं जिन्हें बदला जा सकता है। इसकी एक या अधिक विधियाँ वस्तु की सामग्री को बदल देंगी, या उसके पास एक गुण होगा, जब लिखा जाएगा, तो वस्तु का मूल्य बदल जाएगा।

यदि आपके पास एक परिवर्तनशील वस्तु StringBufferहै- स्ट्रिंग के समान सबसे अधिक है - तो आपको इसकी एक प्रति बनानी होगी यदि आप पूरी तरह से सुनिश्चित होना चाहते हैं कि यह आपके नीचे से नहीं बदलेगा। यही कारण है कि उत्परिवर्तित वस्तुएँ किसी भी रूप में Dictionaryया सेट में कुंजियों के रूप में उपयोग करने के लिए खतरनाक होती हैं- वे वस्तुएँ जो स्वयं परिवर्तित हो सकती हैं, और डेटा संरचना को जानने का कोई तरीका नहीं होगा, जो भ्रष्ट डेटा के लिए अग्रणी होगा, अंततः, आपके प्रोग्राम को क्रैश कर देगा।

हालाँकि, आप इसकी सामग्री को बदल सकते हैं- इसलिए यह पूर्ण प्रतिलिपि बनाने की तुलना में बहुत अधिक मेमोरी कुशल है, क्योंकि आप एक एकल वर्ण, या कुछ समान बदलना चाहते थे।

आम तौर पर, सही काम यह है कि आप कुछ बनाते समय उत्परिवर्तित वस्तुओं का उपयोग करें, और आपके द्वारा किए जाने के बाद अपरिवर्तनीय वस्तुएँ। यह उन वस्तुओं पर लागू होता है जिनके अपरिवर्तनीय रूप हैं, ज़ाहिर है; अधिकांश संग्रह नहीं हैं। संग्रह के केवल-पढ़ने के रूपों को प्रदान करना अक्सर उपयोगी होता है, हालांकि, जो अपरिवर्तनीय के बराबर होता है, जब आपके संग्रह की आंतरिक स्थिति को अन्य संदर्भों में भेजते हैं- अन्यथा, कुछ उस रिटर्न मान को ले सकता है, इसके लिए कुछ कर सकता है, और अपना भ्रष्ट कर सकता है डेटा।


12

अपरिवर्तनीय:

जब आप किसी ऑब्जेक्ट पर कुछ ऑपरेशन करते हैं, तो यह एक नई ऑब्जेक्ट बनाता है इसलिए स्ट्रिंग के मामले में स्थिति संशोधित नहीं होती है।

परिवर्तनशील

जब आप किसी ऑब्जेक्ट पर कुछ ऑपरेशन करते हैं, तो ऑब्जेक्ट स्वयं ही कोई नया अवरोध नहीं बनाता है जैसा कि स्ट्रिंगबर्ल के मामले में बनाया गया है


8

.NET System.String (उर्फ स्ट्रिंग) में एक अपरिवर्तनीय वस्तु है। इसका मतलब है कि जब आप एक वस्तु बनाते हैं तो आप इसे बदल नहीं सकते हैं बाद में इसका मूल्य होता है। आप केवल एक अपरिवर्तनीय वस्तु को फिर से बना सकते हैं।

System.Text.StringBuilder System.String के परस्पर बराबर है और आप इसके मूल्य का जाप कर सकते हैं

उदाहरण के लिए:

class Program
{
    static void Main(string[] args)
    {

        System.String str = "inital value";
        str = "\nsecond value";
        str = "\nthird value";

        StringBuilder sb = new StringBuilder();
        sb.Append("initial value");
        sb.AppendLine("second value");
        sb.AppendLine("third value");
    }
}

MSIL निम्नलिखित उत्पन्न करता है: यदि आप कोड की जांच करते हैं। आप देखेंगे कि जब भी आप System की किसी वस्तु का जाप करते हैं। तो वास्तव में आप नया निर्माण कर रहे हैं। लेकिन System.Text.StringBuilder में जब भी आप टेक्स्ट का मूल्य बदलते हैं तो आप ऑब्जेक्ट को दोबारा नहीं बनाते हैं।

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       62 (0x3e)
  .maxstack  2
  .locals init ([0] string str,
           [1] class [mscorlib]System.Text.StringBuilder sb)
  IL_0000:  nop
  IL_0001:  ldstr      "inital value"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "\nsecond value"
  IL_000c:  stloc.0
  IL_000d:  ldstr      "\nthird value"
  IL_0012:  stloc.0
  IL_0013:  newobj     instance void [mscorlib]System.Text.StringBuilder::.ctor()
  IL_0018:  stloc.1
  IL_0019:  ldloc.1
  IL_001a:  ldstr      "initial value"
  IL_001f:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
  IL_0024:  pop
  IL_0025:  ldloc.1
  IL_0026:  ldstr      "second value"
  IL_002b:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendLine(string)
  IL_0030:  pop
  IL_0031:  ldloc.1
  IL_0032:  ldstr      "third value"
  IL_0037:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendLine(string)
  IL_003c:  pop
  IL_003d:  ret
} // end of method Program::Main

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

6

स्ट्रिंग्स उत्परिवर्तनीय हैं क्योंकि .NET दृश्य के पीछे स्ट्रिंग पूल का उपयोग करता है। इसका मतलब :

string name = "My Country";
string name2 = "My Country";

नाम और name2 दोनों स्ट्रिंग पूल से एक ही मेमोरी स्थान का उल्लेख कर रहे हैं। अब मान लें कि आप name2 को बदलना चाहते हैं:

name2 = "My Loving Country";

यह स्ट्रिंग "माई लविंग कंट्री" के लिए स्ट्रिंग पूल में दिखेगा, अगर आपको यह मिल जाता है तो आपको इसका संदर्भ अन्य बुद्धिमान नई स्ट्रिंग "माई लविंग कंट्री" में बनाया जाएगा। लेकिन यह पूरी प्रक्रिया " मेरा देश " नहीं बदली गई क्योंकि नाम जैसे अन्य चर अभी भी इसका उपयोग कर रहे हैं। और यही कारण है कि स्ट्रिंग IMMUTABLE हैं

StringBuilder अलग तरीके से काम करती है और स्ट्रिंग पूल का उपयोग नहीं करती है। जब हम StringBuilder का कोई उदाहरण बनाते हैं:

var address  = new StringBuilder(500);

यह इस उदाहरण के लिए आकार 500 बाइट्स की मेमोरी चंक आवंटित करता है और सभी ऑपरेशन इस मेमोरी लोकेशन को संशोधित करते हैं और यह मेमोरी किसी अन्य ऑब्जेक्ट के साथ साझा नहीं की जाती है। और वह कारण है कि है StringBuilder है परिवर्तनशील

मुझे उम्मीद है इससे मदद मिलेगी।


5

कोई नहीं, वास्तव में। स्ट्रिंग क्लास उत्परिवर्तनीय है।

unsafe
{
    string foo = string.Copy("I am immutable.");
    fixed (char* pChar = foo)
    {
        char* pFoo = pChar;

        pFoo[5] = ' ';
        pFoo[6] = ' ';
    }

    Console.WriteLine(foo); // "I am   mutable."
}

इस तरह के तर्क वास्तव में स्ट्रिंग और स्ट्रिंगबर्ल वर्गों में हर समय किए जाते हैं। वे हर बार जब आप कॉनैट, सबस्ट्रिंग आदि को कॉल करते हैं, तो एक नया स्ट्रिंग आवंटित करते हैं और नए स्ट्रिंग को कॉपी करने के लिए सूचक अंकगणितीय का उपयोग करते हैं। स्ट्रिंग्स सिर्फ खुद को म्यूट नहीं करते हैं, इसलिए उन्हें "अपरिवर्तनीय" क्यों माना जाता है।


वैसे, इस स्ट्रिंग स्ट्रिंग के साथ प्रयास करें या आप अपने कार्यक्रम को बुरी तरह से गड़बड़ कर देंगे:

string bar = "I am a string.";

fixed (char* pChar = bar)
{
    char* pBar = pChar;

    pBar[2] = ' ';
}

string baz = "I am a string.";

Console.WriteLine(baz); // "I  m a string."

इसका कारण यह है कि स्ट्रिंग .NET शाब्दिकों को डेस्कटॉप .NET फ्रेमवर्क में इंटर्न किया जाता है; दूसरे शब्दों में, barऔर bazठीक उसी स्ट्रिंग की ओर इशारा करते हैं, इसलिए एक को बदलना दूसरे को बदलना होगा। यह सब ठीक है और बांका है, हालांकि अगर आप WinRT जैसे मानवरहित प्लेटफॉर्म का उपयोग कर रहे हैं, जिसमें स्ट्रिंग इंटर्निंग का अभाव है।


1
सही है। यदि आप खुले अमूर्त को बंद करके नियमों को तोड़ते हैं, जिसे बंद किया जाना है, तो लगभग कुछ भी अपरिवर्तनीय नहीं है। आप गंदा प्रतिबिंब का उपयोग करके जावा में अनुरूप चीजें कर सकते हैं ... लेकिन जेएलएस बताता है कि आपको जो व्यवहार मिलता है वह अपरिभाषित है।
स्टीफन सी।

2

स्पष्ट करने के लिए C # (या .NET सामान्य रूप से) में एक उत्परिवर्तनीय स्ट्रिंग जैसी कोई चीज नहीं है। अन्य लेसेस म्यूटेबल स्ट्रिंग्स (स्ट्रिंग जो बदल सकते हैं) का समर्थन करते हैं लेकिन .NET फ्रेमवर्क नहीं करता है।

तो आपके प्रश्न का सही उत्तर है सभी स्ट्रिंग C # में अपरिवर्तनीय हैं।

स्ट्रिंग का एक विशिष्ट अर्थ है। "स्ट्रिंग" लोअरकेस कीवर्ड केवल System.String वर्ग से तात्कालिक वस्तु के लिए एक शॉर्टकट है। स्ट्रिंग क्लास से निर्मित सभी वस्तुएँ हमेशा अपरिवर्तनीय होती हैं।

यदि आप पाठ का एक परिवर्तनशील प्रतिनिधित्व चाहते हैं, तो आपको स्ट्रिंगब्रुइस्ट जैसे अन्य वर्ग का उपयोग करने की आवश्यकता है। StringBuilder आपको पुनरावृत्त करने के लिए 'शब्दों' का एक संग्रह बनाने की अनुमति देता है और फिर इसे एक स्ट्रिंग (एक बार फिर अपरिवर्तनीय) में परिवर्तित करता है।


क्षमा करें, लेकिन इसके लिए Microsoft दस्तावेज़ StringBuilderविरोधाभासी है: देखें msdn.microsoft.com/en-us/library/…
स्टीफन C

1

डेटा मान परिवर्तित नहीं किया जा सकता है। नोट: परिवर्तनशील मान को परिवर्तित किया जा सकता है, लेकिन मूल अपरिवर्तनीय डेटा मान को छोड़ दिया गया था और स्मृति में एक नया डेटा मान बनाया गया था।


1

कार्यान्वयन में विस्तार।

CLR2 का System.String उत्परिवर्तनीय है। StringBuilder.App कॉल String.AppendInplace (निजी विधि)

CLR4 का System.String अपरिवर्तनीय है। StringBuilder चाउन्किंग के साथ चार सरणी है।


0

से http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/

संक्षिप्त उत्तर: स्ट्रिंग अपरिवर्तनीय है - जबकि स्ट्रिंगबर्बुल परस्पर है।

इसका क्या मतलब है ? विकी कहता है: ऑब्जेक्ट-ओरिएंटेड में, एक अपरिवर्तनीय ऑब्जेक्ट एक ऑब्जेक्ट है, जिसकी स्थिति निर्मित होने के बाद संशोधित नहीं की जा सकती है। यह एक उत्परिवर्तित वस्तु के विपरीत है, जिसे बनने के बाद संशोधित किया जा सकता है।

StringBuilder वर्ग प्रलेखन से:

स्ट्रिंग ऑब्जेक्ट अपरिवर्तनीय है। जब भी आप System.String वर्ग में से किसी एक विधि का उपयोग करते हैं, तो आप मेमोरी में एक नई स्ट्रिंग ऑब्जेक्ट बनाते हैं, जिसके लिए उस नए ऑब्जेक्ट के लिए स्थान का एक नया आवंटन आवश्यक होता है।

ऐसी स्थितियों में जहां आपको एक स्ट्रिंग में बार-बार संशोधन करने की आवश्यकता होती है, एक नई स्ट्रिंग ऑब्जेक्ट बनाने के साथ जुड़े ओवरहेड महंगा हो सकता है।

System.Text.StringBuilder वर्ग का उपयोग तब किया जा सकता है जब आप एक नई वस्तु बनाए बिना एक स्ट्रिंग को संशोधित करना चाहते हैं। उदाहरण के लिए, StringBuilder वर्ग का उपयोग करते हुए प्रदर्शन को बढ़ावा दे सकता है जब एक लूप में एक साथ कई तारों को समेटना।


0

यहां इम्यूटेबल स्ट्रिंग और म्यूटेबल स्ट्रिंग बिल्डर के लिए उदाहरण दिया गया है

        Console.WriteLine("Mutable String Builder");
        Console.WriteLine("....................................");
        Console.WriteLine();
        StringBuilder sb = new StringBuilder("Very Good Morning");
        Console.WriteLine(sb.ToString());
        sb.Remove(0, 5);
        Console.WriteLine(sb.ToString());

        Console.WriteLine();

        Console.WriteLine("Immutable String");
        Console.WriteLine("....................................");
        Console.WriteLine();
        string s = "Very Good Morning";
        Console.WriteLine(s);
        s.Substring(0, 5);
        Console.WriteLine(s);
        Console.ReadLine();

यह बहुत अच्छा होगा यदि आप आउटपुट के साथ ही @ गोकुल :)
रॉय ली

सबस्ट्रिंग अंतर्निहित मूल्य को नहीं बदलता है। यह केवल एक मूल्य देता है।
क्ये

@ क्यों और क्यों? क्योंकि तार अपरिवर्तनीय हैं :)
LuckyLikey

आपका 2 लाइन कोड -: s.Substring (0, 5); Console.WriteLine (रों); यहाँ s.substring () s नहीं बदलता है। यदि स्ट्रिंग अपरिवर्तनीय है, तो यह उदाहरण नहीं दिखाता है।
धनंजय

0

C # में स्ट्रिंग अपरिवर्तनीय है। यदि आप इसे किसी भी स्ट्रिंग के साथ समेटते हैं, तो आप वास्तव में एक नई स्ट्रिंग बना रहे हैं, वह है नई स्ट्रिंग ऑब्जेक्ट! लेकिन StringBuilder उत्परिवर्ती स्ट्रिंग बनाता है।


0

StringBuilder एक बड़ी डेटा स्ट्रिंग को समेटने का एक बेहतर विकल्प है क्योंकि StringBuilder एक उत्परिवर्तनीय स्ट्रिंग प्रकार है और StringBuilder ऑब्जेक्ट एक अपरिवर्तनीय प्रकार है, इसका मतलब है कि स्ट्रिंग को सम्‍मिलित करते समय StringBuilder ऑब्जेक्ट का एक नया उदाहरण कभी नहीं बनाता है।

यदि हम संघनन के लिए प्राप्त करने के लिए स्ट्रिंगबर्ल के बजाय स्ट्रिंग का उपयोग कर रहे हैं तो यह हर बार स्मृति में नया उदाहरण पैदा करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.