Kode seperti teks.ToUpper() terlihat seperti mengubah isi variabel, padahal kenyataannya tidak. Tipe string di C# bersifat immutable: setelah objek string dibuat, isinya tidak pernah berubah. Runtime hanya membuat objek string baru setiap kali operasi teks dijalankan. Sifat ini mempengaruhi cara kita menulis kode sehari-hari, mulai dari menampung hasil method hingga mengukur biaya penggabungan teks dalam loop.

Bukti Operasi Menghasilkan String Baru #

Method ReferenceEquals melaporkan apakah dua variabel menunjuk objek yang sama persis di memori. Dengan method tersebut, kita bisa membuktikan bahwa hasil operasi teks adalah objek baru:

csharp
string nama = "Siti Rahma";
string atas = nama.ToUpper();

Console.WriteLine(nama);
Console.WriteLine(atas);
Console.WriteLine(ReferenceEquals(nama, atas));

string sambungan = nama + ", S.Pd";
Console.WriteLine(ReferenceEquals(nama, sambungan));

Output yang Dihasilkan:

text
Siti Rahma
SITI RAHMA
False
False

Mari kita telaah baris demi baris:

  1. Baris 2 (nama.ToUpper()): Method mengembalikan string baru berisi SITI RAHMA; string asal "Siti Rahma" tidak tersentuh, sehingga baris 4 masih mencetak bentuk aslinya.
  2. Baris 5 (ReferenceEquals(nama, atas)): Hasil False menunjukkan keduanya objek berbeda di memori.
  3. Baris 7 (nama + ", S.Pd"): Operator + juga menyusun string baru, bukan menambah isi string lama; perbandingan referensinya kembali False.

Perbandingan == pada String #

Meskipun string adalah tipe referensi, operator == pada string membandingkan isinya, bukan alamatnya:

csharp
string a = "Budi";
string b = "Budi";
Console.WriteLine(a == b);
Console.WriteLine(ReferenceEquals(a, b));

Output yang Dihasilkan:

text
True
True

a == b menghasilkan True karena isi kedua variabel sama. Hasil ReferenceEquals yang juga True berasal dari string interning: compiler menempatkan literal yang sama ke satu objek bersama, sehingga dua literal "Budi" menunjuk satu objek. Perilaku ini khusus literal; string hasil operasi runtime tidak ikut diinterning secara otomatis.

Pola Penulisan Ulang #

Karena operasi mengembalikan string baru, hasil method yang tidak ditampung akan terbuang. Pola yang benar adalah menugaskan kembali hasilnya ke variabel:

csharp
string kata = "gorengan";
kata.Replace("goreng", "bak");
Console.WriteLine(kata);

kata = kata.Replace("goreng", "bak");
Console.WriteLine(kata);

Output yang Dihasilkan:

text
gorengan
bakan

Pemanggilan pertama kata.Replace(...) menghasilkan "bakan", tetapi hasilnya tidak ditampung, sehingga kata tetap "gorengan". Pemanggilan kedua menugaskan hasilnya kembali ke kata, dan pencetakan menampilkan "bakan".