Apa perbedaan antara string yang dapat berubah dan tidak berubah dalam C #?
Apa perbedaan antara string yang dapat berubah dan tidak berubah dalam C #?
Jawaban:
Mutable dan immutable adalah kata-kata bahasa Inggris yang berarti "bisa berubah" dan "tidak bisa berubah". Arti kata-katanya sama dalam konteks IT; yaitu
Arti dari kata-kata ini adalah sama dalam C # / .NET seperti pada bahasa pemrograman lain / lingkungan, meskipun (jelas) nama-nama jenis mungkin berbeda, seperti detail lainnya.
Untuk catatan:
String
adalah tipe string default C # / .Net StringBuilder
adalah tipe string C # / .Net yang dapat diubah Untuk "efek perubahan" pada string yang direpresentasikan sebagai C # String
, Anda benar-benar membuat String
objek baru . Dokumen asli String
tidak diubah ... karena tidak dapat diubah.
Dalam kebanyakan kasus lebih baik digunakan String
karena lebih mudah alasannya; mis. Anda tidak perlu mempertimbangkan kemungkinan bahwa beberapa utas lainnya mungkin "mengubah string saya". Namun, ketika Anda perlu membuat atau memodifikasi string menggunakan urutan operasi, mungkin lebih efisien untuk menggunakan a StringBuilder
.
Dan akhirnya, bagi orang-orang yang menyatakan bahwa a StringBuilder
bukan string karena tidak dapat diubah, dokumentasi Microsoft menjelaskan sebagai StringBuilder
berikut:
"Merupakan string karakter yang bisa berubah . Kelas ini tidak dapat diwarisi."
String
tidak kekal
yaitu string tidak dapat diubah. Ketika Anda mengubah string (dengan menambahkannya misalnya), Anda sebenarnya membuat string baru.
Tetapi StringBuilder
tidak kekal (melainkan bisa berubah)
jadi jika Anda harus mengubah string berkali-kali, seperti beberapa penggabungan, kemudian gunakan StringBuilder
.
O(N^2)
perilaku ...
Suatu objek bisa berubah jika, begitu dibuat, keadaannya dapat diubah dengan memanggil berbagai operasi di atasnya, jika tidak maka tidak dapat diubah.
Dalam C # (dan .NET) string diwakili oleh kelas System.String. Kata string
kunci adalah alias untuk kelas ini.
Kelas System.String tidak dapat diubah, yaitu sekali dibuat kondisinya tidak dapat diubah .
Jadi semua operasi Anda lakukan pada string seperti Substring
, Remove
, Replace
, Rangkaian menggunakan operator + 'dll akan membuat string baru dan mengembalikannya.
Lihat program berikut untuk demonstrasi -
string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);
Ini akan mencetak 'string' dan 'mystring' masing-masing.
Untuk manfaat keabadian dan mengapa string tidak dapat diubah periksa Mengapa .NET String tidak dapat diubah? .
Jika Anda ingin memiliki string yang ingin Anda modifikasi sering Anda bisa menggunakan StringBuilder
kelas. Operasi pada StringBuilder
instance akan memodifikasi objek yang sama .
Untuk saran lebih lanjut tentang kapan menggunakan StringBuilder
merujuk ke Kapan menggunakan StringBuilder? .
Semua string
objek tidak berubah dalam C #. Objek kelas string
, sekali dibuat, tidak akan pernah bisa mewakili nilai apa pun selain yang dibangun dengan mereka. Semua operasi yang tampaknya "mengubah" sebuah string malah menghasilkan yang baru. Ini tidak efisien dengan memori, tetapi sangat berguna untuk dapat percaya bahwa string tidak akan berubah bentuk di bawah Anda - karena selama Anda tidak mengubah referensi Anda, string yang dirujuk tidak akan pernah berubah.
Objek yang bisa berubah, sebaliknya, memiliki bidang data yang dapat diubah. Satu atau lebih metode akan mengubah konten objek, atau memiliki Properti yang, ketika ditulis ke dalam, akan mengubah nilai objek.
Jika Anda memiliki objek yang dapat diubah - yang paling mirip dengan String adalah StringBuffer
- maka Anda harus membuat salinannya jika Anda ingin benar-benar yakin itu tidak akan berubah dari bawah Anda. Inilah sebabnya mengapa objek yang dapat diubah berbahaya untuk digunakan sebagai kunci ke dalam bentuk Dictionary
atau set apa pun - objek itu sendiri dapat berubah, dan struktur data tidak memiliki cara untuk mengetahui, yang mengarah ke data yang korup yang pada akhirnya akan membuat crash program Anda.
Namun, Anda dapat mengubah isinya- jadi itu, jauh lebih efisien memori daripada membuat salinan lengkap karena Anda ingin mengubah satu karakter, atau sesuatu yang serupa.
Secara umum, hal yang benar untuk dilakukan adalah menggunakan objek yang bisa berubah saat Anda membuat sesuatu, dan objek yang tidak dapat diubah begitu Anda selesai. Ini berlaku untuk objek yang memiliki bentuk tidak berubah, tentu saja; sebagian besar koleksi tidak. Seringkali berguna untuk menyediakan bentuk-bentuk koleksi read-only, meskipun, yang setara dengan kekal, ketika mengirimkan keadaan internal koleksi Anda ke konteks lain- jika tidak, sesuatu dapat mengambil nilai pengembalian, melakukan sesuatu untuk itu, dan merusak Anda data.
Abadi
Ketika Anda melakukan beberapa operasi pada objek, itu menciptakan objek baru sehingga keadaan tidak dapat dimodifikasi seperti dalam kasus string.
Yg mungkin berubah
Ketika Anda melakukan beberapa operasi pada suatu objek, objek itu sendiri memodifikasi tidak ada objek baru yang dibuat dalam kasus StringBuilder
Dalam .NET System.String (alias string) adalah objek yang tidak berubah. Itu berarti ketika Anda membuat objek Anda tidak dapat mengubah nilainya setelah itu. Anda hanya dapat membuat ulang objek yang tidak dapat diubah.
System.Text.StringBuilder adalah bisa berubah setara dengan System.String dan Anda dapat memotong nilainya
Sebagai contoh:
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");
}
}
Hasilkan MSIL berikut: Jika Anda menyelidiki kode. Anda akan melihat bahwa setiap kali Anda memotong objek dari System.String Anda benar-benar membuat yang baru. Tetapi dalam System.Text.StringBuilder setiap kali Anda mengubah nilai teks Anda tidak membuat ulang objek.
.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
String bisa berubah karena .NET menggunakan string pool di belakang layar. Itu berarti :
string name = "My Country";
string name2 = "My Country";
Nama dan name2 merujuk ke lokasi memori yang sama dari kumpulan string. Sekarang anggaplah Anda ingin mengubah name2 menjadi:
name2 = "My Loving Country";
Ini akan mencari string pool untuk string "My Loving Country", jika ditemukan Anda akan mendapatkan referensi itu string baru yang bijak lainnya "My Loving Country" akan dibuat di string pool dan name2 akan mendapatkan referensi itu. Tetapi seluruh proses " My Country " ini tidak berubah karena variabel lain seperti nama masih menggunakannya. Dan itulah alasan mengapa string IMMUTABLE .
StringBuilder bekerja dengan cara yang berbeda dan tidak menggunakan string pool. Saat kami membuat instance dari StringBuilder:
var address = new StringBuilder(500);
Ini mengalokasikan potongan memori ukuran 500 byte untuk contoh ini dan semua operasi hanya mengubah lokasi memori ini dan memori ini tidak dibagi dengan objek lain. Dan itu adalah alasan mengapa StringBuilder adalah bisa berubah .
Saya harap ini akan membantu.
Sebenarnya tidak ada. Kelas String bisa berubah.
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."
}
Logika semacam ini dilakukan sepanjang waktu di kelas String dan StringBuilder. Mereka hanya mengalokasikan string baru setiap kali Anda memanggil Concat, Substring, dll. Dan menggunakan aritmatika pointer untuk menyalin ke string baru. String tidak bermutasi, karenanya mengapa mereka dianggap "tidak berubah".
Omong-omong, jangan coba - coba ini dengan string literal atau Anda akan mengacaukan program Anda:
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."
Ini karena string literal diinternir di desktop .NET Framework; dengan kata lain, bar
dan baz
arahkan ke string yang sama persis, sehingga bermutasi satu akan bermutasi yang lain. Ini semua bagus dan bagus jika Anda menggunakan platform yang tidak dikelola seperti WinRT, yang tidak memiliki string interning.
Untuk memperjelas tidak ada yang namanya string yang bisa berubah di C # (atau .NET secara umum). Bahasa lainnya mendukung string yang dapat diubah (string yang dapat berubah) tetapi .NET framework tidak.
Jadi jawaban yang benar untuk pertanyaan Anda adalah SEMUA string tidak dapat diubah dalam C #.
string memiliki arti tertentu. kata kunci "string" huruf kecil hanyalah pintasan untuk objek yang dibuat dari kelas System.String. Semua objek yang dibuat dari kelas string SELALU tidak dapat diubah.
Jika Anda ingin representasi teks yang dapat diubah maka Anda perlu menggunakan kelas lain seperti StringBuilder. StringBuilder memungkinkan Anda membangun koleksi 'kata' secara iteratif dan kemudian mengubahnya menjadi string (sekali lagi tidak dapat diubah).
StringBuilder
kontradiksi ini: lihat msdn.microsoft.com/en-us/library/…
Nilai data tidak dapat diubah. Catatan: Nilai variabel dapat diubah, tetapi nilai data tidak berubah asli dibuang dan nilai data baru dibuat dalam memori.
Dari http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/
Jawaban Singkat: String tidak dapat diubah - sedangkan StringBuilder bisa berubah.
Apa artinya ? Wiki mengatakan: Dalam berorientasi objek, objek yang tidak dapat diubah adalah objek yang kondisinya tidak dapat diubah setelah dibuat. Ini berbeda dengan objek yang bisa berubah, yang dapat dimodifikasi setelah dibuat.
Dari dokumentasi Kelas StringBuilder:
Objek String tidak dapat diubah. Setiap kali Anda menggunakan salah satu metode di kelas System.String, Anda membuat objek string baru di memori, yang membutuhkan alokasi ruang baru untuk objek baru itu.
Dalam situasi di mana Anda perlu melakukan modifikasi berulang pada string, overhead yang terkait dengan membuat objek String baru bisa mahal.
Kelas System.Text.StringBuilder dapat digunakan ketika Anda ingin memodifikasi string tanpa membuat objek baru. Misalnya, menggunakan kelas StringBuilder dapat meningkatkan kinerja saat menyatukan banyak string dalam satu lingkaran.
Berikut adalah contoh untuk string Immutable dan Mutable builder
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();
String dalam C # tidak berubah. Jika Anda menggabungkannya dengan string apa pun, Anda sebenarnya membuat string baru, yaitu objek string baru! Tapi StringBuilder menciptakan string yang bisa berubah.
StringBuilder adalah pilihan yang lebih baik untuk menggabungkan string data yang sangat besar karena StringBuilder adalah tipe string yang dapat berubah dan objek StringBuilder adalah tipe yang tidak dapat diubah, yang berarti StringBuilder tidak pernah membuat instance objek baru saat menggabungkan string.
Jika kita menggunakan string alih-alih StringBuilder untuk mencapai concatenation maka itu akan membuat instance baru dalam memori setiap waktu.