Seberapa jauh harus 'var' dan operator penggabungan nol '??' dihibur tanpa menghambat keterbacaan?

23

Saya tahu judul pertanyaan itu sangat subyektif, tetapi saya dihadapkan dengan penggunaan ??operator oleh rekan-rekan saya, di mana pada saat yang sama saya tidak terlalu senang / nyaman menerapkan varkode baru yang akan datang.

Argumen yang diberikan untuk menggunakan ??operator adalah, menghilangkan keterbacaan dalam kode.

Pertanyaan saya adalah, bukankah hal yang sama terjadi ketika Anda mulai menggunakan var?

Numan
sumber
49
Jika "pengembang" tidak dapat memahami ??operator penggabungan nol setelah dijelaskan, mereka tidak boleh berada di dekat kode produksi.
CaffGeek
12
Saya sarankan kita mengubah operator dari ?? untuk IfNullThen. ? bisa jadi IfSoChoose,: adalah ElseChoose. + adalah Tambah. - adalah Kurangi, kecuali itu unary, maka itu Negatif. - dibagi antara DecrementBeforeUsing, dan DecrementAfterUsing. Di C ++ Anda bisa melakukan ini dengan makro.
Lee Louviere
7
@ Xade: Itu ironi, bukan? ... benar? ... Tuhan biarkan itu menjadi ironi (dan saya seorang ateis).
Steven Jeuris
10
@ SevenJeuris Ini mungkin sarkasme , tapi itu bukan ironi .
Kirk Broadhurst
1
@KirkBroadhurst: Saya berdiri dikoreksi , selalu membingungkan keduanya.
Steven Jeuris

Jawaban:

53

Operator penggabungan nol (??)

Secara pribadi, saya tidak melihat kelemahan menggunakan operator ini. Pertimbangkan tiga contoh kode berikut, dari operator baru 'mudah' hingga 'kompleks'.

Tanpa sihir:

bool isNameSet = false;
string name;
if ( isNameSet )
{
    Console.WriteLine( name );
}
else
{
    Console.WriteLine( "No name set." );
}

Operator ternary:

bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );

Null penggabungan:

string name = null;
Console.WriteLine( name ?? "No name set." );

Alasan operator ini ditemukan adalah karena mereka mewakili operasi pemrograman yang sangat umum . Tidak ingin menggunakannya karena Anda tidak terbiasa hanya keras kepala . Bahasa berevolusi, fitur berevolusi, belajar menggunakannya!

kata kunci var

Saya memiliki pendapat yang agak berbeda tentang kata kunci var. Jenis variabel sering memberikan informasi tambahan tentang kode Anda. Saya menemukan menyembunyikan jenis dengan menggunakan kata kunci var kadang membuat kode kurang dibaca. Anda tidak tahu apa yang diharapkan tanpa menggunakan pelengkapan otomatis, atau melayang di atas pengidentifikasi untuk melihat apa yang sebenarnya. Menurut pendapat saya, ini menghasilkan kode yang lebih lambat untuk membaca / menulis.

Saya menggunakan kata kunci ketika saya menemukan bahwa jenisnya tidak memberikan banyak informasi tambahan.

  • Terutama di loop foreach , yang saya pelajari dari Resharper karena merupakan pengaturan di sana. Sebagian besar waktu, Anda tahu jenis koleksi yang Anda lalui, sehingga Anda tahu Anda mengharapkan barang dari dalam koleksi itu.
  • Permintaan Linq . Hasil kueri linq seringkali merupakan tipe generik yang sangat kompleks. Menampilkan jenis ini tidak lebih berbahaya daripada kebaikan.
  • Nama ketik panjang yang diinisialisasi dengan konstruktornya. Anda sudah bisa tahu apa jenisnya dengan melihat konstruktor.

Sebagai contoh untuk pernyataan terakhir:

ThisIsSomeSpecializedTypeRightHere duplication =
    new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
    new ThisIsSomeSpecializedTypeRightHere();  // Less duplication.

// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();
Steven Jeuris
sumber
24
Contoh terakhir persis ketika kata kunci var dapat unggul. Bayangkan bahwa kode dikotori di seluruh kode Anda. Factory.CreateSomeTypekembali IEnumerable<SomeType>. Suatu hari, untuk alasan apa pun, itu berubah untuk kembali SomeType[]. Jika Anda telah menggunakan var, itu hanya kompilasi ulang.
pdr
1
Dapatkan contoh itu dengan cara yang salah lalu pergi mencari makanan. Numpty! Contoh yang lebih baik adalah menggunakan milik Anda. Bagaimana jika Factory.CreateSomeType()perubahan mengembalikan suatu ISomeType?
pdr
4
@ pdr: Itu kemungkinan besar berarti antarmuka juga berubah, dan perilaku perlu disesuaikan / ditambahkan juga. Jika itu sederhana, ganti nama saja, tentu saja, Anda telah mengganti nama otomatis. Jika 'kontrak' berubah, saya lebih suka melihat kode saya rusak sehingga saya dapat melihat apakah saya harus menyesuaikan sesuatu atau tidak.
Steven Jeuris
2
Saya pikir itu jauh lebih mungkin bahwa jika mengembalikan jenis beton menjadi mengembalikan antarmuka yang hanya memungkinkan untuk jenis beton lainnya dengan antarmuka yang sama (konsisten dengan pola Pabrik). Tetapi jika kontrak berubah maka kode Anda akan rusak - meskipun Anda mungkin menemukan itu hanya rusak dalam beberapa kasus di mana itu penting daripada di mana-mana.
pdr
1
@ Tom Hawtin, kita semua tahu itu tak terhindarkan untuk dihindari nullsepenuhnya. Selain itu, semakin saya mencari alternatif null, semakin saya sadari menggunakan nullkadang-kadang solusi terbersih. Contoh yang saya berikan adalah IMHO yang tidak terlalu buruk, dan saya menganggapnya sebagai penggunaan yang sesuai untuk jenis yang dapat dibatalkan.
Steven Jeuris
16

var memungkinkan kode verbose lebih sedikit, yang meningkatkan keterbacaan. Menurut pendapat saya, keterbacaan tidak boleh diukur dengan berapa banyak detail yang Anda lihat, tetapi berapa banyak detail yang disembunyikan pada pandangan pertama. Selain contoh Linq, var memungkinkan pengetikan bebek pada level kode sumber, dengan memberikan contoh berikut:

...
foreach (var message in messages) {
  var label = Factory.CreateLabel();
  label.Text = message;
  Controls.Add(label);
}
...

Siapa yang peduli apa jenis label asalkan memberikan properti Teks?

Codism
sumber
Seseorang berusaha memahami apakah ini misalnya label winforms atau label WPF.
Steven Jeuris
14
@ Seven Jeuris: itu biasanya informasi konteks yang diketahui. Jika tidak, Anda mendekati kode dengan cara yang salah.
Codism
Seseorang yang ingin tahu apakah itu label WPF default atau label kustom? :)
Steven Jeuris
14
1. Haruskah orang itu benar-benar peduli, asalkan itu label dengan properti Teks? 2. Jika ini adalah salah satu kasus langka yang BENAR-BENAR mereka miliki untuk dirawat, tanyakan Intellisense. 3. Jika mereka mengedit kode dalam IDE tanpa Intellisense, mereka mungkin memiliki ketidaknyamanan yang jauh lebih besar daripada 'var' :)
KutuluMike
4
Seseorang dengan perasaan abstraksi yang buruk.
Jim Balter
16

Saya tidak memiliki komentar serius pada ??operator, karena saya tidak pernah menggunakan bahasa dengan operator seperti itu. Mengenai var, orang memprogram dalam bahasa seperti Ruby, Python, Perl dan PHP yang sepenuhnya mengetik secara implisit sepanjang waktu. Penduduk asli dari bahasa-bahasa ini menyadari bahwa tipe formal suatu variabel biasanya adalah noise yang tidak relevan. Anda lebih tertarik pada variabel apa yang bisa dilakukan , yaitu antarmuka struktural / bebek.

Demikian pula, saya kebanyakan program di D. D diketik secara statis tetapi memiliki autokata kunci, yang setara dengan var. Itu dianggap idiom untuk menggunakannya di mana-mana kecuali Anda melihat kebutuhan khusus untuk menekankan jenis sesuatu kepada pembaca atau (melalui konversi implisit) kompiler. Kecuali kadang-kadang ketika digunakan sebagai tipe fungsi kembali (ini diperbolehkan dalam D), saya tidak pernah menemukan itu untuk menghambat keterbacaan, karena saya kebanyakan berpikir dalam hal struktural / antarmuka bebek, bukan tipe formal / nominatif, ketika saya memprogram.

Selain itu, IMHO menggunakan di varmana saja mungkin adalah contoh yang baik KERING. Jenis sesuatu harus ditentukan dalam satu dan hanya satu tempat, dan kemudian secara otomatis diperbanyak kapan pun perlu diperbanyak. Jika Anda menggunakan vardan tipe formal dari variabel perlu diubah di beberapa titik, perubahan yang diperlukan akan secara otomatis diperbanyak di mana pun diperlukan oleh kompiler selama program masih tipe-benar, daripada programmer harus secara manual mengubah setiap instance . Ini adalah Good Thing (TM).

dsimcha
sumber
13

Saya pikir ini adalah pertanyaan untuk tim pada akhirnya. Jika itu tidak dapat dibaca oleh orang lain di tim saya maka saya tidak akan menggunakannya, meskipun saya mungkin mencoba beberapa kali untuk meyakinkan mereka dengan contoh, atau dengan menunjukkan singkatan analagous (seperti + =) yang mereka temukan lebih mudah dibaca.

Namun, jika bekerja sendiri maka saya temukan ?? dan var mudah dibaca tanpa batas. Bahkan

var a = b ?? c ?? d ?? e ?? "";

cukup jelas bagi saya.

Operator ternary dan dynamicmerupakan hal yang berbeda, tentu saja.

pdr
sumber
4
Saya akan menggunakan `String.Empty 'di sini.
Pekerjaan
1
@ Ayub, dalam kejujuran, aku juga. Aku akan meletakkan sesuatu di string itu, maka tidak bisa memikirkan apa pun :)
pdr
4
var a = b ?? c ?? d ?? e ?? String.Empty ?? "";
Lee Louviere
2
@ Xaade Anda tidak pernah bisa cukup yakin. Tapi sungguh, menggunakan String.Empty atau "" adalah preferensi pribadi. Saya menggunakan "" karena lebih pendek ...
Carra
12
@Xaade - jika String.Emptypernah kembali null, kita berada dalam satu neraka dari banyak kode yang rusak.
Jesse C. Slicer
10

Argumen yang diberikan untuk menggunakan ?? operator itu, menghilangkan keterbacaan dalam kode.

Memikirkannya sebentar, komentar ini memberi tahu saya orang yang membuat komentar, tidak memahaminya sebagaimana mestinya. Kemungkinan besar itu benar dalam situasi tertentu, tetapi secara keseluruhan, saya tidak mengabaikan sesuatu yang menurut tim C # cukup penting untuk ditambahkan karena "keterbacaan". Saya menempatkan ini dalam kategori yang sama dari if(boolean_object)vs if(boolean_object == true). Beberapa orang berpendapat bahwa yang kedua lebih mudah dibaca, tetapi pada kenyataannya itu hanya menambahkan kode tambahan untuk seseorang untuk membaca / mengetik, dan dalam beberapa situasi dapat lebih membingungkan (berpikir if(boolean_object != false))

Pertanyaan saya adalah, bukankah hal yang sama terjadi ketika Anda mulai menggunakan var?

Tim C # telah memungkinkan Anda untuk tidak menentukan sesuatu yang Anda tahu apa yang akan terjadi. Kecuali saya benar-benar perlu mendefinisikan apa yang akan menjadi variabel (baik itu sangat penting bahwa objek kembali adalah tipe x, atau itu benar-benar tidak dapat dibaca), saya gunakan var. var x = "MY_STRING";Saya tahu ini string dari melihatnya. Sebenarnya, saya tidak benar-benar peduli bahwa itu adalah string selama itu melakukan apa yang saya butuhkan. Mendefinisikan tipe variabel adalah untuk keuntungan saya, bukan milik kompiler. Jika ada sesuatu yang salah, kompiler akan memberi tahu saya ketika itu berjalan jika saya memiliki tipe variabel yang salah.

kemiller2002
sumber
0

Menurut saya, varkata kunci yang digunakan adalah yang terbaik dalam situasi di mana ia diperkenalkan - permintaan LINQ. Dalam kueri ini, jenis hasil yang dikembalikan sering kali memiliki beberapa nama yang berbelit-belit besar yang sulit ditentukan sebelumnya dan tidak membantu pemahaman pembaca tentang apa yang kode Anda lakukan.

Namun, melakukan var text = "Some text " + variableName + "some more text."itu hanya malas.

EDIT: @Jorg Anda melompat pada jawaban yang sengaja disederhanakan tetapi tidak menambahkan apa pun pada diskusi. OK, bagaimana dengan ini untuk contoh yang lebih baik: var items = doc.DocumentElement.FirstChild.ChildNodes;Jika Anda dapat mengetahui jenis dari itu saya akan memberi Anda cookie.

Josh Earl
sumber
18
Jika Anda tidak dapat mengetahui bahwa itu "Some text "adalah string, maka Anda memiliki masalah yang jauh lebih besar untuk dikhawatirkan daripada jumlah vars dalam kode Anda.
Jörg W Mittag
3
Masalahnya bukan var; masalahnya adalah nama variabel jelek "item". Jika Anda menggunakan nama variabel yang baik, tidak ada yang salah dengan itu var.
Kyralessa
3
Saya menduga (tanpa melihat) bahwa item adalah kumpulan node XML, yang saya harapkan memiliki semua properti dan metode kumpulan node XML, dan hanya itu yang perlu saya ketahui.
KutuluMike
Jika Anda perlu tahu apa jenis var singkatan dan tidak bisa langsung tahu dengan melihat, cukup arahkan mouse di atasnya. Tidak butuh banyak waktu untuk melakukannya.
scrwtp
1
"hanya malas" - Ini bukan argumen yang menentangnya. Sebenarnya, itu sama sekali tidak cerdas.
Jim Balter
0

Saya punya masalah mendasar dengan menggunakan var.

Dalam contoh ini semuanya berdampingan, tetapi masalahnya sebenarnya dengan solusi besar dengan perpustakaan atau proyek bersama.

Pertimbangkan ini:

public MyFirstObject GetMeAnObject() {
    return new MyFirstObject();
}

public void MainProgram() {
    var theObject = GetMeAnObject();
    theObject.PerformOperation();
}

Apa yang terjadi jika GetMeAnObject diubah, oleh orang lain, sesuai dengan kebutuhan mereka?

public MySecondObject GetMeAnObject() {
    return new MySecondObject();
}

Metode MainProgram akan memiliki kesalahan merah besar pada .PerformOperation (). Apa yang terjadi? PerformOperation bekerja dengan sangat baik sebelumnya. Kami melihat metode diObject dan hanya menghilang tanpa jejak. Itu ada di sana terakhir kali, dan kita perlu metode itu. Anda bisa menghabiskan waktu yang lama mengejar ekor dan mencoba mencari tahu mengapa, jika MyFirstObject memiliki metode yang disebut PerformOperation, sekarang tidak dapat dilihat. Semua orang "tahu" bahwa GetMeAnObject mengembalikan MyFirstObject, jadi tidak ada gunanya memeriksa itu.

Jika Anda secara eksplisit mengetikkanObject maka Anda akan memiliki kesalahan Cast Tidak Valid pada baris yang memanggil GetMeAnObject, dan akan sangat jelas bahwa GetMeAnObject mengembalikan jenis yang tidak seperti yang Anda harapkan.

Singkatnya, deklarasi eksplisit berarti Anda tahu apa artinya kesalahan. Pemain yang tidak valid berarti Anda mengharapkan satu jenis dan jenis lainnya dikembalikan. Anggota yang tidak dikenal berarti anggota tersebut tidak dikenal.

Hugh Phoenix-Hulme
sumber
10
Seorang rekan kerja membuat perubahan besar dalam kode yang tidak dicakup oleh tes, dan Anda pikir masalahnya var? Bahasa tidak dapat diharapkan untuk melindungi terhadap perilaku semacam itu - bagaimana jika mereka memodifikasi MyFirstObject secara langsung? Itu masih akan rusak, tetapi tidak ada sintaks yang bisa menyelamatkan Anda dari itu. Saya menganggap ini sebagai kekuatan var, bahkan: bagaimana jika alih-alih mengembalikan MySecondObject, Anda sekarang malah mengembalikan IMyFirstObject?
Phoshi
2
"Semua orang" tahu "bahwa GetMeAnObject mengembalikan MyFirstObject, jadi tidak ada gunanya memeriksa itu." Saya tidak dapat benar-benar memikirkan skenario dalam pemrograman di mana saya akan benar-benar bergantung pada memori saya tentang apa yang GetMeAnObject jika saya debug. Jika saya memeriksa bahwa PerformOperation tidak ada di sana, saya akan melihat kode dan tidak ada untuk kelas lain. Jika dalam suatu IDE kelas akan muncul contoh saya melihat jenis objek. Sebenarnya, ketika kompiler memberitahu saya kesalahan, itu akan mengatakan 'kelas MySecondObject tidak memiliki operasi PerformOperation'. Bagaimana itu untuk semua orang tahu?
Muhammad Alkarouri