Inisialisasi string default: NULL atau Empty? [Tutup]

130

Saya selalu menginisialisasi string saya ke NULL, dengan pemikiran bahwa NULL berarti tidak adanya nilai dan "" atau String.Empty adalah nilai yang valid. Saya telah melihat lebih banyak contoh belakangan ini dari kode di mana String.Empty dianggap sebagai nilai default atau tidak mewakili nilai. Ini menurut saya aneh, dengan tipe nullable yang baru ditambahkan di c # sepertinya kami mengambil langkah mundur dengan string dengan tidak menggunakan NULL untuk mewakili 'No Value'.

Apa yang Anda gunakan sebagai penginisialisasi default dan mengapa?

Sunting: Berdasarkan jawaban saya lanjutkan pemikiran saya selanjutnya

  1. Menghindari penanganan kesalahan Jika nilainya tidak boleh nol, mengapa harus diatur ke NULLtempat pertama? Mungkin akan lebih baik untuk mengidentifikasi kesalahan di tempat itu terjadi daripada menutupinya melalui seluruh basis kode Anda?

  2. Menghindari cek nol. Jika Anda bosan melakukan cek nol dalam kode, bukankah lebih baik mengabstraksi cek nol? Mungkin membungkus (atau memperpanjang!) Metode string untuk membuatnya NULLaman? Apa yang terjadi jika Anda terus-menerus menggunakan String.Emptydan null terjadi untuk masuk ke sistem Anda, apakah Anda mulai menambahkan NULLcek?

Mau tak mau aku kembali ke pendapat bahwa itu adalah kemalasan. Setiap DBA akan menampar Anda sembilan cara untuk konyol jika Anda menggunakan '' alih-alih nulldalam database-nya. Saya pikir prinsip-prinsip yang sama berlaku dalam pemrograman dan harus ada seseorang untuk menampar mereka yang terbalik yang menggunakan String.Emptydaripada NULLtidak mewakili nilai.

Pertanyaan-pertanyaan Terkait

ayolah
sumber
'The ware'? Tidak harus menjadi Dana yang saya tahu.
vfilby
@ Joel, saya kagum dengan berapa banyak orang yang tidak tahu tentang Zim atau GIR. Saya juga kagum pada beberapa teman saya yang merasa menjijikkan. Tidak mengatakan itu murni kebaikan, tetapi ada banyak nugget humor di sana.
vfilby
Aku tahu, tapi kadang-kadang menyenangkan berpura-pura sebaliknya.
Dana the Sane
1
Saya mengalami masalah ini pada koleksi formulir MVC atau variabel sesi banyak, saya menemukan hal yang paling berguna adalah untuk mengkonversi null ke String.Empty dengan ?? singkatan, dan kemudian menerapkan operasi string apa pun yang diperlukan. misalnya. (item ?? String.Empty) .Trim (). ToUpper ()
sonjz
4
ini tidak konstruktif ??
nawfal

Jawaban:

111

+1 untuk membedakan antara "kosong" dan NULL. Saya setuju bahwa "kosong" berarti "valid, tetapi kosong" dan "NULL" berarti "tidak valid."

Jadi saya akan menjawab pertanyaan Anda seperti ini:

kosong ketika saya menginginkan nilai default yang valid yang mungkin atau tidak dapat diubah, misalnya, nama tengah pengguna.

NULL ketika itu adalah kesalahan jika kode berikutnya tidak menetapkan nilai secara eksplisit.

Adam Liss
sumber
11
Membedakan antara NULL dan kosong itu bagus ketika sebenarnya ada perbedaan di antara keduanya. Namun, ada banyak kasus di mana tidak ada perbedaan, dan dengan demikian memiliki dua cara untuk mewakili hal yang sama adalah kewajiban.
Greg Smalter
6
@ Greg: Walaupun saya setuju bahwa varietas memiliki potensi kebingungan, ini juga bisa menjadi aset yang hebat. Konvensi penulisan "" atau NULL yang sederhana dan konsisten untuk membedakan antara nilai yang valid dan tidak valid akan membuat kode Anda lebih mudah dimengerti. Inilah sebabnya saya selalu menguji boolean dengan "if (var)," pointer dengan "if (var! = NULL)" dan bilangan bulat dengan "if (var! = 0)" - semuanya memiliki arti yang sama dengan kompiler, tetapi mereka membawa informasi tambahan yang membantu pengembang miskin yang menjaga kode saya.
Adam Liss
32

Menurut MSDN :

Dengan menginisialisasi string dengan Emptynilai alih-alih null, Anda dapat mengurangi peluang NullReferenceExceptionterjadinya.

Namun selalu menggunakan IsNullOrEmpty()adalah praktik yang baik.

Tomalak
sumber
45
Hanya karena Anda mengurangi kemungkinan pengecualian tidak berarti pengecualian itu tidak boleh terjadi. Jika kode Anda bergantung pada nilai yang ada di sana, ia harus mengeluarkan pengecualian!
rmeador
1
Tentu, tidak ada argumen di sana. OTOH, jika Anda hanya menambahkan string bersama ... Saya pikir itu tergantung pada gaya pengkodean, pengalaman dan situasi.
Tomalak
Ini terutama yang saya gunakan membedakan mana yang harus digunakan juga.
PositiveGuy
3
Jangan lupa IsNullOrWhiteSpace () untuk .NET framework 4+
Coops
13

Mengapa Anda ingin string Anda diinisialisasi sama sekali? Anda tidak harus menginisialisasi variabel ketika Anda mendeklarasikan variabel, dan IMO, Anda hanya harus melakukannya ketika nilai yang Anda tetapkan valid dalam konteks blok kode.

Saya sering melihat ini:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else
{
  name = "bar";
}

return name;

Tidak menginisialisasi ke nol akan sama efektifnya. Selain itu, paling sering Anda ingin nilai diberikan. Dengan menginisialisasi ke nol, Anda berpotensi kehilangan jalur kode yang tidak memberikan nilai. Seperti itu:

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else if (othercondition)
{
  name = "bar";
}

return name; //returns null when condition and othercondition are false

Ketika Anda tidak menginisialisasi ke nol, kompiler akan menghasilkan kesalahan yang mengatakan bahwa tidak semua jalur kode menetapkan nilai. Tentu saja, ini adalah contoh yang sangat sederhana ...

Matthijs


sumber
Dalam Visual Studio, yang saya percaya hampir setiap programmer menggunakan C #, situasi kedua Anda (tanpa = null) akan menghasilkan peringatan, untuk alasan persis yang Anda nyatakan - tidak masalah apakah nilai default sebuah string adalah nol. jika Anda tidak menjamin penugasan melalui setiap jalur kode, IDE (dan / atau saya kira kompiler yang mendasari [?]) akan menghasilkan peringatan. Meskipun peringatan tidak akan mencegah kompilasi, mereka masih ada - meninggalkan yang mudah dipecahkan dapat membantu mengaburkan yang lain yang mungkin membutuhkan perhatian programmer
Code Jockey
sepengetahuan saya, situasi pertama akan sangat bahagia tanpa inisialisasi nameke null(tidak ada peringatan), karena setiap jalur kode memberikan nilai untuk name- tidak perlu diinisialisasi sama sekali
Code Jockey
8

Untuk sebagian besar perangkat lunak yang sebenarnya bukan perangkat lunak pemrosesan string, logika program tidak boleh bergantung pada konten variabel string. Setiap kali saya melihat sesuatu seperti ini di sebuah program:

if (s == "value")

Saya mendapat firasat buruk. Mengapa ada string literal dalam metode ini? Pengaturan apa s? Apakah ia tahu bahwa logika bergantung pada nilai string? Apakah ia tahu bahwa huruf kecil harus bekerja? Haruskah saya memperbaiki ini dengan mengubahnya untuk digunakan String.Compare? Haruskah saya membuat Enumdan menguraikannya?

Dari perspektif ini, seseorang dapat sampai pada filosofi kode yang cukup sederhana: Anda menghindari memeriksa konten string sedapat mungkin. Membandingkan string dengan String.Emptybenar-benar hanya kasus khusus membandingkannya dengan literal: itu sesuatu yang harus dihindari kecuali Anda benar-benar harus melakukannya.

Mengetahui hal ini, saya tidak berkedip ketika melihat sesuatu seperti ini di basis kode kami:

string msg = Validate(item);
if (msg != null)
{
   DisplayErrorMessage(msg);
   return;
}

Saya tahu itu Validatetidak akan pernah kembali String.Empty, karena kami menulis kode yang lebih baik dari itu.

Tentu saja, seluruh dunia tidak berfungsi seperti ini. Ketika program Anda berurusan dengan input pengguna, database, file, dan sebagainya, Anda harus menjelaskan filosofi lain. Di sana, itu adalah tugas kode Anda untuk memaksakan ketertiban pada kekacauan. Bagian dari urutan itu adalah mengetahui kapan string kosong berarti String.Emptydan kapan seharusnya artinya null.

(Hanya untuk memastikan saya tidak berbicara keluar dari pantat saya, saya hanya mencari basis kode kami untuk `String.IsNullOrEmpty '. Semua 54 kejadian itu adalah dalam metode yang memproses input pengguna, mengembalikan nilai dari skrip Python, memeriksa nilai yang diambil dari API eksternal, dll.)

Robert Rossney
sumber
6

Ini sebenarnya adalah lubang menganga dalam bahasa C #. Tidak ada cara untuk mendefinisikan string yang tidak bisa nol. Ini menyebabkan masalah sesederhana yang Anda gambarkan, yang memaksa pemrogram untuk membuat keputusan yang tidak harus mereka buat, karena dalam banyak kasus NULL dan String. Kekosongan berarti hal yang sama. Itu, pada gilirannya, nantinya dapat memaksa programmer lain harus menangani NULL dan String.Empty, yang menjengkelkan.

Masalah yang lebih besar adalah bahwa basis data memungkinkan Anda untuk mendefinisikan bidang yang memetakan ke string C #, tetapi bidang basis data dapat didefinisikan sebagai BUKAN NULL. Jadi, tidak ada cara untuk secara akurat mewakili, katakanlah, bidang varchar (100) TIDAK NULL dalam SQL Server menggunakan tipe C #.

Bahasa lain, seperti Spec #, bolehkan ini.

Menurut pendapat saya, ketidakmampuan C # untuk mendefinisikan sebuah string yang tidak mengizinkan null sama buruknya dengan ketidakmampuan sebelumnya untuk mendefinisikan sebuah int yang memungkinkan null.

Untuk sepenuhnya menjawab pertanyaan Anda: Saya selalu menggunakan string kosong untuk inisialisasi default karena lebih mirip dengan cara kerja tipe data database. (Sunting: Pernyataan ini sangat tidak jelas. Seharusnya berbunyi "Saya menggunakan string kosong untuk inisialisasi default ketika NULL adalah keadaan berlebihan, dengan cara yang sama saya mengatur kolom database sebagai BUKAN NULL jika NULL akan menjadi keadaan berlebihan. Demikian pula , banyak kolom DB saya diatur sebagai TIDAK NULL, jadi ketika saya membawanya ke string C #, string akan kosong atau memiliki nilai, tetapi tidak akan pernah menjadi NULL. Dengan kata lain, saya hanya menginisialisasi string ke NULL jika null memiliki arti yang berbeda dari arti String.Empty, dan saya menemukan case tersebut kurang umum (tetapi orang-orang di sini telah memberikan contoh yang sah dari case ini). ")

Greg Smalter
sumber
Menggunakan String.Empty hanya mirip dengan salah satu cara string database didefinisikan. Menggunakan null untuk mewakili tidak ada nilai jauh lebih kongruen dengan nvarchar nol. Saya pikir setiap DBA bernilai garam mereka akan menampar Anda sembilan cara untuk konyol jika Anda menggunakan '' untuk tidak mewakili nilai.
vfilby
Sebenarnya, Greg, Anda salah paham. Ini adalah tipe nilai non-nullable yang paling sedikit "bagaimana tipe database bekerja" karena mereka tidak pernah bisa memiliki nol, dan dengan demikian tidak pernah bisa memetakan ke kolom nullable. Dalam kontrak, string apa pun dapat dipetakan ke kolom varchar apa pun.
Tor Haugen
Anda benar, pernyataan terakhir saya tidak cukup jelas. Sering kali, kolom database saya TIDAK NULL (karena tidak akan ada perbedaan antara arti string kosong dan NULL), jadi saya berusaha untuk menjaga string saya tetap sama dengan tidak pernah menyimpan null di dalamnya, dan itulah yang saya maksudkan.
Greg Smalter
5

Tergantung.

Apakah Anda perlu mengetahui apakah nilainya hilang (apakah mungkin untuk tidak didefinisikan)?

Apakah string kosong nilai yang valid untuk penggunaan string itu?

Jika Anda menjawab "ya" untuk keduanya, maka Anda ingin menggunakan null. Kalau tidak, Anda tidak dapat membedakan antara "tidak ada nilai" dan "string kosong".

Jika Anda tidak perlu tahu apakah tidak ada nilai maka string kosong mungkin lebih aman, karena memungkinkan Anda untuk melewatkan cek nol di mana pun Anda menggunakannya.

Herms
sumber
3

Saya juga mengaturnya ke "" atau null - Saya selalu memeriksa dengan menggunakan String.IsNullOrEmpty, jadi tidak masalah.

Tetapi geek dalam diri saya mengatakan saya harus mengaturnya ke nol sebelum saya memiliki nilai yang tepat untuk itu ...

Coder bedah
sumber
3

Saya selalu mendeklarasikan string dengan string.empty;

Ervin Ter
sumber
2

Apakah mungkin ini merupakan teknik penghindaran kesalahan (disarankan atau tidak ..)? Karena "" masih berupa string, Anda dapat memanggil fungsi string di atasnya yang akan menghasilkan pengecualian jika "NULL?

Dana si Sane
sumber
1
Itulah alasan yang biasanya saya dengar, hanya terdengar seperti kemalasan. "Saya tidak ingin repot memeriksa nilai ini jadi saya akan mengambil jalan pintas" begitulah menurut saya.
vfilby
Ya, saya tidak setuju. Mungkin ada beberapa situasi di mana mengurangi jumlah kode pemeriksaan kesalahan itu bagus, tetapi pemanggilan fungsi yang tidak berpengaruh juga tidak terbesar ..
Dana the Sane
2

Saya selalu menginisialisasi mereka sebagai NULL.

Saya selalu gunakan string.IsNullOrEmpty(someString)untuk memeriksa nilainya.

Sederhana.

Murni
sumber
1

Itu tergantung situasi. Dalam kebanyakan kasus saya menggunakan String.Empty karena saya tidak ingin melakukan pemeriksaan nol setiap kali saya mencoba menggunakan string. Itu membuat kode jauh lebih sederhana dan Anda cenderung memperkenalkan NullReferenceException yang tidak diinginkan.

Saya hanya mengatur string ke null ketika saya perlu tahu apakah sudah diatur atau belum dan di mana string kosong adalah sesuatu yang valid untuk mengaturnya. Dalam praktiknya, saya menemukan situasi ini jarang terjadi.

Rob Prouse
sumber
1

String kosong adalah nilai (sepotong teks yang, kebetulan, tidak mengandung huruf apa pun). Null menandakan tidak ada nilai.

Saya menginisialisasi variabel menjadi nol ketika saya ingin menunjukkan bahwa mereka tidak menunjuk atau mengandung nilai aktual - ketika tujuannya adalah untuk tidak ada nilai.

yfeldblum
sumber
1

Mengulangi respons Tomalak, perlu diingat bahwa ketika Anda menetapkan variabel string ke nilai awal nol, variabel Anda tidak lagi menjadi objek string; sama dengan objek apa pun di C #. Jadi, jika Anda mencoba mengakses metode atau properti apa pun untuk variabel Anda dan Anda menganggap itu adalah objek string, Anda akan mendapatkan pengecualian NullReferenceException.

Michael Ritchson
sumber
1

Null hanya boleh digunakan dalam kasus-kasus di mana nilai opsional. Jika nilainya tidak opsional (seperti 'Nama' atau 'Alamat'), maka nilainya tidak boleh nol. Ini berlaku untuk database serta POCO dan antarmuka pengguna. Null berarti "nilai ini opsional, dan saat ini tidak ada."

Jika bidang Anda bukan opsional, maka Anda harus menginisialisasi sebagai string kosong. Untuk menginisialisasi sebagai null akan menempatkan objek Anda ke keadaan tidak valid (tidak valid oleh model data Anda sendiri).

Secara pribadi saya lebih suka string agar tidak dapat nullable secara default, tetapi hanya nullable jika kita mendeklarasikan "string?". Meskipun mungkin ini tidak layak atau logis pada tingkat yang lebih dalam; tidak yakin.

Dave Cousineau
sumber
0

String bukan tipe nilai, dan tidak akan pernah ;-)

Tor Haugen
sumber
0

Saya pikir tidak ada alasan untuk tidak menggunakan null untuk nilai yang belum ditetapkan (atau di tempat ini dalam aliran program tidak terjadi). Jika Anda ingin membedakan, ada == null. Jika Anda hanya ingin memeriksa nilai tertentu dan tidak peduli apakah itu nol atau sesuatu yang berbeda, String.Equals ("XXX", MyStringVar) tidak apa-apa.

Volker
sumber