Haruskah saya menggunakan .ToString () ketika menggabungkan variabel string dan integer di C #?


19
int a = 1;
int b = 2;
int sum = a + b;
string expression = "Expression: " + a + " + " + b + " = " + sum;
Console.WriteLine(expression); //displays Expression 1 + 2 = 3

Haruskah saya menggunakan:

string expression = "Expression: " + a + " + " + b + " = " + sum;

atau

string expression = "Expression: " + a.ToString() + " + " + b.ToString() + " = " + result.ToString();

Apakah disarankan untuk digunakan ToString()saat penggabungan stringdan int?


6
Dalam a + "" + b + ""atau "" + a + b + "", itu tidak masalah: itu semua penggabungan string. Di a + b + ""dalamnya itu penting: adan bditambahkan pertama.
Tim S.

4
Catatan: Di VB.NET, ambiguitas ini dihindari dengan memiliki operator penggabungan string yang eksplisit : "Expression: " + aakan menampilkan kesalahan waktu kompilasi (dengan Opsi Strict On), "Expression: " & aakan melakukan penggabungan string.
Heinzi

Kode pertama akan menghasilkan tinju (int ke Int32), yang kedua tidak. Yang kedua jelas lebih cepat.
Abjad Acak

Jawaban:


33

ToString pemakaian

Tidak, Anda tidak boleh menggunakannya di ToStringsini.

Rangkaian string secara otomatis mengubah non-string menjadi string, yang berarti bahwa dua varian Anda hampir sama:

Ketika satu atau kedua operan bertipe string, operator penjumlahan yang telah ditentukan menggabungkan representasi string dari operan.

Sumber: C # Bahasa Spesifikasi: Operator tambahan, MSDN .

Di sisi lain, yang pertama (tanpa ToString):

  • Lebih pendek untuk menulis,
  • Lebih pendek untuk dibaca,
  • Lebih mudah untuk mempertahankan dan:
  • menunjukkan dengan tepat maksud penulis: untuk menyatukan string.

Jadi lebih suka yang pertama.

Dibawah tenda

Yang juga menarik adalah melihat apa yang terjadi di bawah tenda. Salah satu cara untuk melihatnya adalah dengan menonton kode IL dalam LINQPad. Program ini:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = a + b;
    Console.WriteLine(c);
}

diterjemahkan ke IL berikut:

IL_0001:  ldc.i4.3    
IL_0002:  stloc.0     // a
IL_0003:  ldstr       " Hello"
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  box         System.Int32
IL_000F:  ldloc.1     // b
IL_0010:  call        System.String.Concat
IL_0015:  stloc.2     // c
IL_0016:  ldloc.2     // c
IL_0017:  call        System.Console.WriteLine

Lihat itu System.String.Concat? Itu berarti bahwa kode asli dapat ditulis juga seperti itu, yang diterjemahkan menjadi IL yang sama persis:

void Main()
{
    var a = 3;
    var b = " Hello";
    var c = string.Concat(a, b); // This is the line which was changed.
    Console.WriteLine(c);
}

Ketika Anda membaca dokumentasistring.Concat(object[]) , Anda dapat belajar bahwa:

Metode menggabungkan setiap objek dalam args dengan memanggil ToStringmetode parameterless objek itu; itu tidak menambahkan pembatas.

Ini artinya ToStringberlebihan. Juga:

String.Empty digunakan sebagai ganti objek null dalam array.

Yang menangani dengan baik kasus di mana beberapa operan adalah nol (lihat catatan kaki 1).

Sementara dalam contoh terakhir, concatenation diterjemahkan ke dalam string.Concat, orang juga harus menyoroti optimasi kompiler:

var a = "Hello " + "World";

diterjemahkan ke dalam:

ldstr       "Hello World"
stloc.0

Di samping itu:

var a = string.Concat("Hello ", "World");

diterjemahkan ke dalam:

ldstr       "Hello "
ldstr       "World"
call        System.String.Concat
stloc.0

Alternatif lain

Tentu saja ada cara lain untuk menggabungkan representasi string dari objek di C #.

  1. StringBuilderdigunakan ketika Anda perlu melakukan banyak operasi penggabungan dan membantu mengurangi jumlah string perantara yang dibuat. Memutuskan apakah Anda harus menggunakan StringBuilderatau gabungan biasa mungkin tidak mudah. Gunakan profiler atau cari jawaban yang relevan di Stack Overflow.

    Menggunakan StringBuildermemiliki kelemahan utama membuat kode sulit dibaca dan dipelihara. Untuk kasus sederhana seperti yang ada dalam pertanyaan Anda, StringBuildertidak hanya berbahaya bagi keterbacaan kode, tetapi juga tidak berguna dalam hal kinerja.

  2. string.Join harus digunakan ketika Anda perlu menambahkan pembatas.

    Jelas, tidak pernah digunakan string.Joindengan pembatas kosong untuk menyatukan string.

  3. string.Formatdapat digunakan ketika string templating lebih disukai daripada string concatenation. Salah satu kasus di mana Anda lebih suka saat pesan dilokalisasi, seperti yang disarankan dalam jawaban oleh kunthet.

    Menggunakan string.Formatmemiliki beberapa kelemahan yang membuatnya tidak cocok untuk kasus sederhana seperti milik Anda:

    • Dengan placeholder "{0}" sederhana, sering tidak jelas parameter mana yang digunakan. Sering kali membalik parameter secara keliru atau melupakannya. Untungnya, C # 6 akhirnya memperkenalkan interpolasi string yang menyelesaikan masalah ini.

    • Kinerja runtime dapat menurun. Tentu saja, jangan menganggap string.Formatini selalu lambat. Jika kinerja penting, ukur dua pendekatan dan tentukan mana yang lebih cepat berdasarkan hasil aktual Anda alih-alih asumsi.

    • Kode ini sedikit lebih panjang untuk ditulis, lebih lama untuk dibaca dan lebih sulit untuk dipelihara, meskipun ini sangat kecil dan seharusnya tidak terlalu mengganggu Anda.


¹ Perbedaannya muncul ketika salah satu objek adalah null. Tanpa ToString, a nulldigantikan oleh string kosong. Dengan ToString, sebuah NullReferenceExceptiondilemparkan.


1
Untuk alasan ini (perilaku yang tidak dapat diprediksi), string gabungan dengan +praktik dianggap buruk di sebagian besar bahasa. Dalam hal ini saya akan gunakan string.Concat, dalam banyak kasus string.Formatlebih baik. Ini tentu bukan Pythonic untuk digunakan +, dan karena PEP 3101 %tidak disarankan juga str.format.
Arda Xi

2
Apakah mengganti string kosong dengan nullbenar - benar "menanganinya dengan baik"? Yah, itu tidak seburuk "pada kesalahan melanjutkan selanjutnya" ...
Deduplicator

Di bawah tenda, jika Anda menggabungkan tanpa memanggil .ToString (), tinju akan terjadi ..., dan Concat(object[])akan digunakan sebagai gantinya Concat(string[]). Jadi "string " + isebenarnya tidak identik dengan"string " + i.ToString()
Abjad Acak

@RandomAlphabets: titik valid. Namun, perbedaannya hanyalah lokasi ToString(): kode OP dalam satu kasus, System.String.Concatimplementasi dalam kasus lain. Jadi, jawabannya tetap valid: jangan menulis kode yang tidak bermanfaat.
Arseni Mourzenko

15

Sebagai gantinya, Anda harus menggunakan string formatter. Lebih mudah untuk memformat nomor Anda menjadi representasi string atau pelokalan. misalnya:

string expression = string.Format("Expression: {0} + {1} = {2}", a, b, sum);

Info lebih lanjut tentang MSDN .

Namun, formatter string kurang dapat dibaca (dan mungkin juga kinerja) daripada penggabungan string.


6
Ingin menjelaskan mengapa opsi ini lebih baik?
Insinyur Dunia

@WorldEngineer: Saya memperbarui penjelasannya.
kunthet

12
Saya tidak tahu tentang orang lain, tetapi saya benar-benar menemukan ini lebih mudah dibaca. Mungkin karena saya tumbuh dengan C di mana s [n] printf adalah satu-satunya pilihan realistis untuk kode semacam ini.
Jules

2
Namun cara ini memberikan tiga sumber kesalahan, bukan satu. Ketika Anda menambahkan sesuatu ke dalam string, Anda 1) harus mengubah format string, 2) jangan lupa untuk menambahkan parameter baru dalam daftar, 3) mencoba untuk memilih tempat yang benar dalam daftar di mana parameter baru harus ditempatkan.
Ruslan

2
Hanya ingin berpadu dan memberi tahu Anda tentang fitur interpolasi string yang akan datang di C # 6 .. Anda akan menulis "Ekspresi: \ {a} + \ {b} = \ {jumlah}" untuk mendapatkan hasil yang sama. codeproject.com/Articles/846566/...
cwap

-2

Jika Anda menggunakan +penggabungan, itu sendiri menggunakan String.Concatmetode. String itu sendiri tidak mengekspos operator +.

sebagai contoh:

int i = 10;
string str = "hello" + i;

dikompilasi menjadi:

int i = 10;
object o1 = "hello";
object o2 = i; // Note boxing
string str = string.Concat(o1, o2);

Jika Anda langsung menelepon ToString, itu akan menghindari tinju dan memanggil Concat(string, string)kelebihan. Karenanya ToStringpanggilan akan sedikit lebih efisien walaupun tidak cukup signifikan. Anda lebih baik pergi dengan contoh yang Anda rasa lebih mudah dibaca.


2
ini tampaknya hanya mengulangi poin-poin yang dibuat dan dijelaskan dalam jawaban sebelumnya : "Rangkaian string secara otomatis mengubah non-string menjadi string ..."
gnat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.