Apakah menggunakan nama parameter yang berbeda dari nama tipe hanya dengan casing dianggap praktik buruk di C #?

43

Saya melihat pertanyaan yang mirip dengan ini sehubungan dengan nama parameter yang cocok dengan properti di kelas, tapi saya tidak dapat menemukan apa pun mengenai menggunakan nama parameter yang sama dengan nama tipe parameter kecuali untuk casing di C #. Sepertinya bukan pelanggaran yang bisa saya temukan, tetapi apakah itu dianggap praktik yang buruk? Sebagai contoh, saya punya metode berikut

public Range PadRange(Range range) {}

Metode ini mengambil rentang, dan mengembalikan rentang baru yang telah menerapkan beberapa lapisan. Jadi, mengingat konteks generik, saya tidak bisa memikirkan nama yang lebih deskriptif untuk parameter. Namun, saya teringat tip yang saya ambil ketika membaca Kode Lengkap tentang "jarak psikologis". Ia mengatakan

Jarak psikologis dapat didefinisikan sebagai kemudahan di mana dua item dapat dibedakan ... Saat Anda melakukan debug, bersiaplah untuk masalah yang disebabkan oleh jarak psikologis yang tidak memadai antara nama variabel yang sama dan antara nama rutin yang serupa. Saat Anda membuat kode, pilih nama dengan perbedaan besar sehingga Anda dapat menghindari masalah.

Tanda tangan metode saya memiliki banyak "Rentang" yang terjadi, jadi rasanya seperti masalah yang berkaitan dengan jarak psikologis ini. Sekarang, saya melihat banyak pengembang melakukan hal berikut

public Range PadRange(Range myRange) {}

Saya pribadi memiliki kebencian yang kuat untuk konvensi ini. Menambahkan awalan "saya" ke nama-nama variabel tidak memberikan konteks tambahan.

Saya juga melihat yang berikut ini

public Range PadRange(Range rangeToPad) {}

Saya suka ini lebih baik daripada awalan "saya", tetapi masih tidak peduli untuk itu secara keseluruhan. Itu hanya terasa terlalu verbal bagi saya, dan membaca dengan canggung sebagai nama variabel. Bagi saya, dipahami bahwa rentang akan diisi karena nama metode.

Jadi dengan semua ini ditata, usus saya akan pergi dengan tanda tangan pertama. Bagi saya, bersih. Tidak perlu memaksakan konteks saat itu tidak diperlukan. Tetapi apakah saya menganggap diri sendiri atau pengembang masa depan merugikan dengan konvensi ini? Apakah saya melanggar praktik terbaik?

Jason Tyler
sumber
35
Jika Anda tidak dapat menemukan parameter yang lebih deskriptif, Range rangetidak masalah.
Robert Harvey
21
Dalam situasi ini, IDE akan mewarnai 'Range' dan 'range' secara berbeda sehingga sangat mudah untuk melihat bahwa satu adalah tipe dan satu adalah nama variabel.
17 dari 26
10
Ya, saya ingat itu. Itu ada dalam pedoman desain mereka sebagai pertimbangan. "PERTIMBANGKAN memberikan properti dengan nama yang sama dengan tipenya." docs.microsoft.com/en-us/dotnet/standard/design-guidelines/…
Jason Tyler
11
Juga baik: Range r(setidaknya untuk badan metode pendek) dan Range toPad.
Bergi
19
Saya selalu menganggap awalan "saya" sebagai sesuatu yang dilakukan dalam kode contoh di mana digunakan untuk menunjukkan kepada pembaca bahwa nama harus diubah ke sesuatu yang lain tergantung pada konteksnya. Itu bukan sesuatu yang seharusnya benar-benar berakhir pada kode nyata apa pun.
kapex

Jawaban:

100

Jangan terlalu memikirkan ini, Range rangetidak apa-apa. Saya menggunakan penamaan seperti itu selama lebih dari 15 tahun di C #, dan mungkin jauh lebih lama di C ++, dan tidak pernah mengalami kekurangan nyata darinya, justru sebaliknya.

Tentu saja, ketika Anda memiliki variabel lokal yang berbeda dalam cakupan yang sama, semua dari jenis yang sama, mungkin akan membantu untuk menginvestasikan beberapa upaya mental untuk membedakan mereka dengan benar.

Doc Brown
sumber
6
Pengecualian lain yang akan saya tambahkan adalah ketika instance sedang melakukan tindakan tertentu di atasnya. Ada sedikit ruang untuk menjadi lebih deskriptif mengapa parameter diperlukan misalnya. Wack (Bozo bozoToBeWacked) Terlebih lagi jika parameternya opsional dan menjelaskan apa arti objek dalam skenario itu / apa pengaruhnya. Aturan praktis saya jika tidak jelas tanpa melihat kode apa parameter tidak maka perlu nama dan / atau komentar yang lebih baik.
Mike
17
Saya akan menganggap Wack(Bozo bozoToBeWacked)sebagai contoh redundansi dalam nama variabel yang banyak diungkapkan oleh metode itu sendiri (dan dengan demikian tidak diinginkan per pertanyaan awal). Wack(Person bozo)lebih bernilai secara semantik, karena menyiratkan bahwa diharapkan hanya bozos yang akan dipecat.
Miral
2
Jika Anda menyebutkan pada paragraf kedua, saya akan sering mengganti nama parameter menjadi sesuatu seperti initialRange. Itu masih sangat umum tetapi tidak memiliki tingkat ketidaksukaan yang hampir sama myRange.
Jaquez
@ Miral: Ini menjadi lebih relevan dalam kasus-kasus seperti Punch(Bozo punchingBozo, Bozo bozoToBePunched). Penamaan terperinci lebih relevan ketika Anda harus membedakan antara banyak hal (yang secara semantik dijelaskan dengan kata-kata yang hampir sama). Saran OP Range rangeToPadtidak perlu dalam contoh metode satu parameternya, tetapi mungkin sangat diperlukan untuk metode yang mengambil beberapa Rangeobjek.
Flater
7
@Flater Punch(Bozo source, Bozo target)akan melakukan pekerjaannya
Thomas Ayoub
17

Saya melakukan ini sepanjang waktu, itu memberi saya banyak pikiran. Jika itu adalah argumen yang diteruskan ke konstruktor yang perlu ditugaskan ke anggota, anggota saya akan dinamai rentang juga dan tugas akan

this.range = range;

Dan saya biasanya memiliki properti bernama Range.

Mereka semua adalah hal yang sama, hanya berbeda dalam konteks sehingga masuk akal untuk mempertahankan satu nama dan Anda harus mengingat hanya satu nama. Ini satu hal, perbedaannya murni teknis.

Anda harus ketat dengan anggota yang memenuhi syarat penuh dengan "ini." meskipun, tapi itu adalah untuk apa StyleCop.

Catatan samping StyleCop

Kontroversi dijamin!

Untuk mereka yang menentang penggunaan "ini.": Saya telah melihat _, m, m_ dan tidak ada apa-apa. Bahasa itu sendiri menawarkan kepada kita cara yang jelas dan universal yang dapat dikenali secara universal untuk menunjukkan bahwa kita berurusan dengan anggota kelas. Mengapa Anda ingin membuat cara Anda sendiri yang mencincang nama yang sudah sempurna?

Satu-satunya alasan saya dapat berpikir bahwa itu adalah kebiasaan lama dari era C, ketika sebenarnya masuk akal untuk melakukannya karena tidak ada cara lain.

"Itu lebih banyak karakter!" Serius? "Waktu kompilasi akan meroket!" Serius? "Aku harus mengangkat kelingkingku saat mengetiknya!" Seolah waktu mengetik memiliki arti penting dalam total waktu pengembangan.

Saya menyadari bahwa gaya apa pun yang berbeda dari apa yang Anda gunakan sebelumnya akan menimbulkan pertentangan. Tetapi menggunakan ini secara konsisten sulit untuk diperdebatkan. Inilah cara kerjanya untuk saya: Sebelum saya mendorong file kode baru saya menjalankan StyleCop dan akan menemukan sejumlah anggota yang tidak memiliki kualifikasi "ini". Saya menempatkan "ini." di clipboard, jalankan oleh anggota dan masukkan. Tidak ada usaha sama sekali.

StyleCop melakukan lebih dari ini (haha). Ada begitu banyak cara yang bisa dilakukan pengembang (hanya mempertimbangkan pemformatan kode) untuk menggagalkan pekerjaan pemeliharaan penggantinya. StyleCop mencegah sebagian besar dari mereka. Itu sangat berharga.

Jika Anda baru mengenalnya: itu biasanya membuat Anda menggerutu selama satu atau dua minggu dan kemudian Anda akan menyukainya.

Martin Maat
sumber
19
" Anda harus tegas dengan anggota yang memenuhi syarat penuh dengan" ini. ", " -1. Jangan gunakan thiskecuali jika penting. Itu hanya suara sebaliknya. Gunakan _rangeuntuk bidang dan thistidak pernah diperlukan kecuali dalam metode ekstensi.
David Arno
12
Saya setuju dengan @DavidArno. 'Ini' hanyalah kebisingan murni. 'Rentang' adalah properti, '_range' adalah bidang, dan 'rentang' adalah parameter.
17 dari 26
8
@ David Jika variabel adalah anggota kelas, itu penting dan mengalahkan setiap awalan sembarang untuk memberi sinyal Anda melihat anggota kelas daripada argumen atau variabel lokal.
Martin Maat
6
IDE saya akan menembak bola api begitu saya menetapkan variabel untuk dirinya sendiri.
Koekje
21
@DavidArno Peduli untuk menjelaskan mengapa "noise" _lebih disukai daripada noise this.? Saya berpendapat satu memiliki makna ditegakkan oleh bahasa (dan biasanya memiliki penyorotan sintaks) sementara yang lain tidak.
Clint
9

Panduan mandiri saya tentang metode, parameter, dan variabel penamaan cukup sederhana:

  1. Jika nama berisi tipe yang diteruskan atau dikembalikan, Anda salah melakukannya.
  2. Sebutkan hal-hal dengan apa yang dimaksudkan, bukan untuk apa.
  3. Ingat selalu bahwa kode lebih banyak dibaca daripada yang tertulis.

Jadi tanda tangan metode optimal, menurut saya, akan menjadi:

Range Pad(Range toPad)

Memperpendek nama metode cukup jelas.

Nama parameter toPadsegera memberi tahu pembaca bahwa parameter itu mungkin akan diubah di tempat dengan menjadi empuk, lalu dikembalikan. Sebaliknya, tidak ada asumsi yang dapat dibuat tentang variabel bernama range.

Lebih lanjut, dalam tubuh sebenarnya dari metode ini, Rangevariabel lain apa pun yang diperkenalkan akan (harus) dinamai berdasarkan niatnya, sehingga Anda mungkin memiliki paddeddan unpadded... toPadsesuai dengan konvensi penamaan tersebut, tetapi rangetetap saja menonjol dan tidak gel.

Ian Kemp
sumber
3
padded/ unpaddedKedengarannya bagus untuk variabel tidak berubah lokal. Tetapi jika ada toPadparameter yang bisa berubah , maka setelah padding dilakukan nama toPadtidak cocok lagi (kecuali hasilnya dikembalikan segera). Saya lebih suka berpegang Range rangepada kasus-kasus itu.
kapex
@ Kapap saya akan menyebutnya saja result. Itu akan dimodifikasi dan dikembalikan . Yang terakhir jelas dari nama dan yang pertama mengikuti, karena mengembalikan argumen yang tidak dimodifikasi tidak masuk akal.
maaartinus
Dari tanda tangan, Padmetode mengembalikan a Range. Bagi saya, itu menyiratkan bahwa yang saya lewati akan dipertahankan, tidak dimodifikasi di tempat, dan yang baru, empuk Rangeakan dikembalikan. .
Aaron M. Eshbach
1
Saya tidak yakin harus memikirkan saran Anda. Pad(toPad)terasa IMHO agak salah. Anda membuat titik yang baik untuk mempertahankan sudut pandang Anda. Anda mendapat +0 dari saya! :)
Eric Duminil
Dalam pertanyaan itu menyatakan bahwa "mengembalikan rentang baru yang telah menerapkan beberapa padding". Saya setuju dengan penamaan Anda untuk skenario yang Anda pikirkan, tetapi untuk pertanyaan sebenarnya, saya akan mencari sesuatu seperti Range CreateRangeWithPadding (Sumber rentang)
Richard Willis
3

Untuk penamaan elemen kode (jenis, variabel, fungsi, apa pun), pertanyaan kunci untuk ditanyakan pada diri sendiri adalah

Jika saya membuat kesalahan ketik, akankah kompiler menemukannya untuk saya?

Jenis terburuk berbasis kesalahan ketik adalah salah satu tempat kode dikompilasi dan dijalankan, tetapi memberikan perilaku yang berbeda dari yang Anda harapkan, dengan alasan yang halus. Dan karena itu karena kesalahan ketik, biasanya sangat sulit untuk melihat ketika Anda memeriksa kode. Jika salah ketik akan menghentikan kompilasi kode, maka kompiler akan menandai baris yang menyebabkan masalah, dan Anda dapat dengan mudah menemukan dan memperbaikinya.

Untuk situasi Anda di mana jenis dan variabel hanya berbeda dalam huruf besar, ini akan selalu menjadi kasus. (Atau hampir selalu - dengan usaha yang cukup, saya yakin Anda bisa membuatnya bekerja, tetapi Anda harus benar-benar mencobanya.) Jadi saya pikir Anda baik-baik saja di sana.

Di mana Anda perlu khawatir akan jika ada dua variabel, metode, fungsi atau properti dalam lingkup saat ini disebut rangedan Range. Dalam hal ini kompiler mungkin akan membiarkannya lewat, dan Anda akan mendapatkan perilaku yang tidak terduga pada saat run-time. Perhatikan bahwa itu adalah dua dari salah satu jenis elemen kode, bukan hanya "dua variabel" atau "dua fungsi" - semua itu dapat secara implisit dilemparkan satu sama lain, dengan pembantaian yang dihasilkan saat dijalankan. Anda mungkin mendapat peringatan, tetapi Anda tidak bisa menjamin lebih dari itu. Anda memiliki masalah serupa jika Anda memiliki dua jenis yang dinyatakan dipanggil rangedan Range.

Perhatikan juga hal yang sama berlaku untuk gaya notasi Hongaria , di mana nama diawali dengan satu atau lebih karakter untuk mengatakan sesuatu lebih banyak tentang apa pun itu. Misalnya, jika Anda memiliki variabel yang dipanggil Rangedan penunjuknya PRange, mudah untuk melewatkannya secara tidak sengaja P, misalnya. C # seharusnya menangkap ini, tetapi C dan C ++ hanya akan memberi Anda peringatan paling banyak. Atau yang lebih mengkhawatirkan, misalkan Anda memiliki versi ganda yang disebut DRangedan Anda menurunkannya ke versi float yang disebut FRange. Gunakan pelampung satu per kecelakaan (yang mudah karena tombol yang berdekatan pada keyboard) dan kode Anda akan jenis pekerjaan, tapi itu akan jatuh dengan cara yang aneh dan tak terduga ketika proses berjalan keluar dari resolusi dan underflows.

Kami tidak lagi pada hari-hari di mana kami memiliki batas penamaan 8 karakter, atau 16 karakter, atau batas sewenang-wenang apa pun. Saya kadang-kadang mendengar novis mengeluh tentang nama variabel yang lebih panjang yang membuat pengkodean lebih lama. Hanya pemula yang mengeluh tentang ini. Para pembuat kode yang serius tahu bahwa yang benar - benar membutuhkan waktu adalah mencari tahu bug-bug yang tidak jelas - dan pilihan penamaan yang buruk adalah cara klasik untuk menjatuhkan diri di lubang tertentu.

Graham
sumber
Hanya catatan untuk pembaca - untuk C #, orang harus benar - benar menghindari Notasi Hongaria. Meskipun ini berguna di masa lalu ketika highlight sintaks bukanlah sesuatu atau terbatas, saat ini itu benar-benar tidak membantu.
T. Sar - Pasang kembali Monica
@ T.Sar Bahkan kembali pada hari itu, saya membencinya dengan penuh gairah! Seperti yang Anda katakan, IDE yang lebih baik telah memecahkan masalah yang ditujukan, tetapi masih sering muncul. Anda masih akan melihatnya jika Anda perlu berbicara dengan Windows API, misalnya, karena alasan historis. Saya tidak ingin benar-benar merusak gaya yang disukai orang-orang jika mereka benar-benar menyukainya, tetapi saya ingin menggunakannya sebagai pengait untuk menunjukkan bahwa huruf besar / kecil bukan satu-satunya cara Anda dapat mengacaukan penamaan.
Graham
Saya sadar bahwa Anda tidak mengusulkan penggunaan Notasi Hongaria, tetapi saya juga sadar bahwa para dev muda memiliki kelemahan besar untuk hal-hal dengan nama keren. Mampu mengatakan "Kode saya ditulis dengan gaya pengkodean ninja super rahasia - Notasi Hongaria!" mungkin terdengar sangat menarik bagi pikiran yang lebih muda. Saya telah melihat terlalu banyak devs menjadi mangsa hype kata-kata keren ... Notasi Hongaria adalah rasa sakit memberikan bentuk kode sumber xX
T. Sar - Reinstate Monica
@ T.Sar Cukup benar. "Mereka yang tidak ingat masa lalu ditakdirkan untuk mengulanginya" dan semua itu. : /
Graham
1
Apakah kita berbicara tentang notasi Hungaria asli atau bagaimana itu salah ditafsirkan oleh Microsoft (dekat "penulis dokumentasi pada tim Windows secara tidak sengaja menemukan apa yang kemudian dikenal sebagai Sistem Hungaria" dan juga dalam wawancara dengan Joel Spolsky oleh Leo Laporte pada episode Triangulasi episode 277, 2016-12-12, 04 mnt 00 dtk - 06 mnt 35 dtk )?
Peter Mortensen
1

Satu anekdot yang ingin saya tambahkan, sementara Range rangeini secara hukum legal, itu bisa membuat hal-hal lebih menantang untuk debug atau refactor. Mencari satu variabel bernama "range" dalam file dengan banyak variabel tipe Range? Anda mungkin akhirnya melakukan lebih banyak pekerjaan nanti sebagai hasil dari pilihan penamaan ini.

Ini sebagian besar tergantung pada konteks. Jika itu adalah file 30 baris, pernyataan saya tidak benar-benar berperan.

Jacob M.
sumber
7
Kebanyakan orang menggunakan alat yang membedakan antara jenis dan parameter atau variabel, untuk pengembangan Windows. Apa yang Anda gambarkan mengingatkan saya pada hari-hari grep yang baik di Unix.
Frank Hileman
1
@ Frankhileman Mungkin mengejutkan Anda, tetapi Unix masih hidup dan grep masih digunakan (: D). Karena grep secara default case-sensitive, masalah yang disebutkan tadi tidak ada. Namun, bahkan kami, pembenci windows-kecanduan terminal, jarang menggunakan grep untuk kode sumber karena IDE jauh lebih baik pada pencarian umum.
maaartinus
Saya pikir kami sepakat bahwa platform bukan itu intinya. grepadalah alat yang hebat, tetapi itu bukan alat refactoring. Dan alat refactoring ada di setiap platform pengembangan yang saya gunakan. (OS X, Ubuntu, Windows).
Eric Wilson
@ EricWilson Pada suatu waktu, grep dan sed adalah satu-satunya alat refactoring di unix.
Frank Hileman
@ Frankhileman Hanya karena sesuatu digunakan sebagai alat refactoring tidak berarti itu salah satunya. Saya bisa refactor di notepad, tetapi itu tidak membuatnya lebih dari editor teks.
Eric Wilson
1

Saya pikir Anda dapat menggunakan Range rangenowdays karena satu alasan: penyorotan sintaksis. IDE modern biasanya menyorot nama tipe dan nama parameter dalam berbagai warna . Juga tipe dan variabel memiliki "jarak logis" yang cukup untuk tidak mudah bingung.

Jika ini tidak terjadi, saya akan mempertimbangkan nama yang berbeda atau mencoba mengaktifkan plugin / ekstensi yang dapat melakukan penyorotan sintaksis ini.

akaltar
sumber
0

Ketika suatu fungsi adalah generik, maka dapat dipastikan bahwa parameternya akan generik, dan karenanya harus memiliki nama generik.

Bukan apa yang Anda katakan, tetapi saya telah melihat fungsi yang melakukan fungsi generik yang memiliki nama parameter yang menyesatkan spesifik. Suka

public String removeNonDigits(String phoneNumber)

Nama fungsi terdengar sangat umum, seperti ini dapat diterapkan pada banyak string dalam banyak situasi. Tapi nama parameternya aneh, membuat saya bertanya-tanya apakah nama fungsinya menyesatkan, atau ... apa?

Jadi yakin, alih-alih mengatakan rentang Range, Anda bisa mengatakan Range rangeToPad. Tetapi informasi apa yang ditambahkan oleh ini? Tentu saja kisaran untuk pad. Apa lagi itu?

Menambahkan beberapa awalan sembarang, "my" atau "m_" atau apa pun, menyampaikan nol informasi tambahan kepada pembaca. Ketika saya menggunakan bahasa di mana kompiler tidak mengizinkan nama variabel sama dengan nama tipe - dengan atau tanpa sensitivitas huruf - saya terkadang memakai awalan atau akhiran, hanya untuk membuatnya dikompilasi . Tapi itu hanya untuk memuaskan kompiler. Orang bisa berpendapat bahwa meskipun kompiler dapat membedakan, ini membuat pembaca manusia lebih mudah untuk membedakan. Tapi wow, di Jawa saya sudah menulis pernyataan seperti "Pelanggan pelanggan = Pelanggan baru ();" satu miliar kali dan saya tidak pernah menganggapnya membingungkan. (Saya selalu merasa sedikit berlebihan dan saya lebih suka seperti itu di VB Anda hanya bisa mengatakan "pelanggan redup sebagai Pelanggan baru" dan Anda tidak harus memberikan nama kelas dua kali.)

Di mana saya DO sangat keberatan dengan nama generik adalah ketika ada dua atau lebih contoh dari jenis yang sama dalam fungsi yang sama. TERUTAMA parameter. Suka:

public Range pad(Range range1, Range range2)

Apa perbedaan antara range1 dan range2? Bagaimana saya bisa tahu? Jika itu adalah sesuatu di mana mereka benar-benar dua nilai generik dan yang dapat dipertukarkan, oke, seperti

public boolean overlap(Range range1, Range range2)

Saya berharap bahwa mengembalikan true jika rentang tumpang tindih dan salah jika tidak, jadi mereka generik dan dapat dipertukarkan.

Tetapi jika mereka berbeda, beri saya petunjuk bagaimana mereka berbeda! Saya baru saja mengerjakan sebuah program baru-baru ini yang memiliki kelas "Tempat" untuk menyimpan data tentang tempat geografis, dan dengan variabel jenis ini bernama "p", "tempat", "tempat2", "myPlace", dll. Wow, itu nama sangat membantu saya menentukan yang mana.

Jay
sumber