Standar pengkodean yang ada pada proyek C # besar mencakup aturan bahwa semua nama jenis sepenuhnya memenuhi syarat, melarang pekerjaan direktif 'menggunakan'. Jadi, daripada yang akrab:
using System.Collections.Generic;
.... other stuff ....
List<string> myList = new List<string>();
(Mungkin tidak mengherankan kalau itu var
juga dilarang.)
Saya berakhir dengan:
System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
Itu peningkatan pengetikan 134%, dengan tidak ada peningkatan yang memberikan informasi bermanfaat. Dalam pandangan saya, 100% peningkatannya adalah noise (kekacauan) yang sebenarnya menghambat pemahaman.
Dalam 30+ tahun pemrograman, saya telah melihat standar yang diusulkan satu atau dua kali, tetapi tidak pernah diterapkan. Alasan di baliknya luput dari saya. Orang yang memaksakan standar itu tidak bodoh, dan saya tidak berpikir dia jahat. Yang membuat salah arah sebagai satu-satunya alternatif lain kecuali aku kehilangan sesuatu.
Pernahkah Anda mendengar standar seperti itu diberlakukan? Jika demikian, apa alasan di baliknya? Bisakah Anda memikirkan argumen selain "itu bodoh," atau "orang lain yang mempekerjakan using
" yang mungkin meyakinkan orang ini untuk menghapus larangan ini?
Pemikiran
Alasan larangan ini adalah:
- Sulit untuk mengarahkan mouse ke atas nama untuk mendapatkan tipe yang sepenuhnya memenuhi syarat. Lebih baik untuk selalu memiliki tipe yang memenuhi syarat terlihat setiap saat.
- Cuplikan kode yang diemail tidak memiliki nama yang sepenuhnya memenuhi syarat, dan karenanya bisa sulit untuk dipahami.
- Saat melihat atau mengedit kode di luar Visual Studio (Notepad ++, misalnya), tidak mungkin untuk mendapatkan nama jenis yang sepenuhnya memenuhi syarat.
Pendapat saya adalah bahwa ketiga kasus ini jarang terjadi, dan membuat semua orang membayar harga kode yang berantakan dan kurang dapat dipahami hanya untuk mengakomodasi beberapa kasus langka adalah salah arah.
Masalah konflik namespace potensial, yang saya harapkan menjadi perhatian utama, bahkan tidak disebutkan. Itu terutama mengejutkan karena kami memiliki namespace MyCompany.MyProject.Core
,, yang merupakan ide yang sangat buruk. Saya sudah lama tahu bahwa menamai sesuatu System
atau Core
dalam C # adalah jalan cepat menuju kegilaan.
Seperti yang orang lain tunjukkan, konflik namespace mudah ditangani oleh refactoring, alias namespace, atau kualifikasi sebagian.
sumber
Jawaban:
Pertanyaan yang lebih luas:
Ya, saya pernah mendengar ini, dan menggunakan nama objek yang memenuhi syarat mencegah tabrakan nama. Meskipun jarang, ketika mereka terjadi, mereka bisa sangat sulit untuk mencari tahu.
Contoh: Jenis skenario itu mungkin lebih baik dijelaskan dengan contoh.
Katakanlah kita memiliki dua
Lists<T>
milik dua proyek terpisah.Saat kami menggunakan nama objek yang sepenuhnya memenuhi syarat, jelas yang
List<T>
digunakan. Kejelasan itu jelas datang dengan mengorbankan kata-kata.Dan Anda mungkin berdebat, "Tunggu! Tidak ada yang akan menggunakan dua daftar seperti itu!" Di situlah saya akan menunjukkan skenario perawatan.
Anda adalah modul tertulis
Foo
untuk perusahaan Anda yang menggunakan perusahaan yang disetujui, dioptimalkanList<T>
.Kemudian, pengembang baru memutuskan untuk memperpanjang pekerjaan yang telah Anda lakukan. Tidak mengetahui standar perusahaan, mereka memperbarui
using
blok:Dan Anda dapat melihat bagaimana semuanya menjadi buruk dengan tergesa-gesa.
Seharusnya sepele untuk menunjukkan bahwa Anda bisa memiliki dua kelas berpemilik dengan nama yang sama tetapi dalam ruang nama yang berbeda dalam proyek yang sama. Jadi ini bukan hanya masalah bertabrakan dengan .NET framework yang disediakan kelas.
Kenyataannya:
Sekarang, apakah ini mungkin terjadi di sebagian besar proyek? Tidak terlalu. Tetapi ketika Anda mengerjakan proyek besar dengan banyak input, Anda melakukan yang terbaik untuk meminimalkan kemungkinan hal-hal meledak pada Anda.
Proyek besar dengan banyak tim yang berkontribusi adalah jenis binatang buas khusus di dunia aplikasi. Aturan yang tampaknya tidak masuk akal untuk proyek lain menjadi lebih relevan karena aliran input ke proyek dan kemungkinan bahwa mereka yang berkontribusi belum membaca pedoman proyek.
Ini juga dapat terjadi ketika dua proyek besar digabung menjadi satu. Jika kedua proyek memiliki kelas yang sama bernama, maka Anda akan melihat tabrakan ketika Anda mulai merujuk dari satu proyek ke yang lain. Dan proyek-proyek mungkin terlalu besar untuk refactor atau manajemen tidak akan menyetujui biaya untuk mendanai waktu yang dihabiskan untuk refactoring.
Alternatif:
Meskipun Anda tidak bertanya, ada baiknya menunjukkan bahwa ini bukan solusi yang bagus untuk masalah tersebut. Bukan ide yang baik untuk membuat kelas yang akan bertabrakan tanpa deklarasi namespace mereka.
List<T>
, khususnya, harus diperlakukan sebagai kata yang dilindungi dan tidak digunakan sebagai nama untuk kelas Anda.Demikian juga, ruang nama individu dalam proyek harus berusaha untuk memiliki nama kelas yang unik. Harus mencoba dan mengingat namespace mana yang
Foo()
sedang Anda kerjakan adalah overhead mental yang sebaiknya dihindari. Mengatakan dengan cara lain: memilikiMyCorp.Bar.Foo()
danMyCorp.Baz.Foo()
akan membuat pengembang Anda tersandung dan sebaiknya dihindari.Jika tidak ada yang lain, Anda bisa menggunakan ruang nama parsial untuk menyelesaikan ambiguitas. Misalnya, jika Anda benar-benar tidak dapat mengganti nama
Foo()
kelas mana pun Anda bisa menggunakan ruang nama parsial mereka:Alasan spesifik untuk proyek Anda saat ini:
Anda memperbarui pertanyaan Anda dengan alasan spesifik Anda diberikan untuk proyek Anda saat ini mengikuti standar itu. Mari kita lihat mereka dan benar-benar menyimpang dari jalan kelinci.
"Tidak praktis?" Um, tidak. Mungkin menjengkelkan. Memindahkan beberapa ons plastik untuk menggeser pointer di layar tidak merepotkan . Tapi saya ngelantur.
Alur penalaran ini tampaknya lebih seperti menutup-nutupi daripada hal lainnya. Begitu saja, saya kira bahwa kelas-kelas dalam aplikasi tersebut bernama lemah dan Anda harus mengandalkan namespace untuk mendapatkan informasi semantik yang sesuai dengan nama kelas.
Ini bukan pembenaran yang valid untuk nama kelas yang sepenuhnya memenuhi syarat, mungkin itu pembenaran yang valid untuk menggunakan nama kelas yang memenuhi syarat sebagian.
Garis penalaran (lanjutan?) Ini memperkuat kecurigaan saya bahwa kelas saat ini tidak disebutkan namanya. Sekali lagi, memiliki nama kelas yang buruk bukanlah pembenaran yang baik untuk mengharuskan semuanya menggunakan nama kelas yang sepenuhnya memenuhi syarat. Jika nama kelas sulit untuk dipahami, ada jauh lebih banyak kesalahan daripada apa yang dapat diperbaiki oleh nama kelas yang memenuhi syarat.
Dari semua alasan, yang satu ini hampir membuat saya mengeluarkan minuman saya. Tapi sekali lagi, saya ngelantur.
Saya bertanya - tanya mengapa tim sering mengedit atau melihat kode di luar Visual Studio? Dan sekarang kita sedang melihat pembenaran yang cukup orthogonal untuk apa ruang nama dimaksudkan untuk menyediakan. Ini adalah argumen yang didukung perkakas sedangkan ruang nama ada untuk menyediakan struktur organisasi untuk kode.
Sepertinya proyek Anda sendiri mengalami konvensi penamaan yang buruk bersama dengan pengembang yang tidak mengambil keuntungan dari apa yang dapat disediakan oleh alat tersebut untuk mereka. Dan alih-alih menyelesaikan masalah-masalah aktual itu, mereka mencoba untuk menampar bantuan pita atas salah satu gejala dan membutuhkan nama kelas yang sepenuhnya memenuhi syarat. Saya pikir aman untuk mengkategorikan ini sebagai pendekatan yang salah arah.
Mengingat bahwa ada kelas-kelas dengan nama buruk, dan dengan asumsi Anda tidak dapat melakukan refactor, jawaban yang benar adalah dengan menggunakan Visual Studio IDE untuk keuntungan penuhnya. Pertimbangkan untuk menambahkan plugin seperti paket VS PowerTools. Kemudian, ketika saya melihat
AtrociouslyNamedClass()
saya dapat mengklik pada nama kelas, tekan F12 dan langsung dibawa ke definisi kelas untuk lebih memahami apa yang coba dilakukan. Demikian juga, saya dapat mengklik Shift-F12 untuk menemukan semua tempat dalam kode yang saat ini harus digunakanAtrociouslyNamedClass()
.Mengenai masalah tooling luar - hal terbaik untuk dilakukan adalah menghentikannya. Jangan mengirim email bolak-balik jika tidak segera jelas apa yang dimaksud. Jangan gunakan alat lain di luar Visual Studio karena alat itu tidak memiliki kecerdasan seputar kode yang dibutuhkan tim Anda. Notepad ++ adalah alat yang luar biasa, tetapi tidak cocok untuk tugas ini.
Jadi saya setuju dengan penilaian Anda mengenai tiga pembenaran khusus yang Anda terima. Yang mengatakan, apa yang saya pikir Anda diberitahu adalah "Kami memiliki masalah mendasar pada proyek ini yang tidak dapat / tidak akan mengatasi dan ini adalah bagaimana kami 'memperbaiki' mereka." Dan itu jelas berbicara tentang masalah yang lebih dalam di dalam tim yang mungkin berfungsi sebagai tanda bahaya bagi Anda.
sumber
usings
tetapi itu tidak terdengar seperti proyek Anda memenuhi syarat sebagai salah satu kasus tersebut.Saya memang bekerja di satu perusahaan di mana mereka memiliki banyak kelas dengan nama yang sama, tetapi di perpustakaan kelas yang berbeda.
Sebagai contoh,
Desain yang buruk, Anda mungkin berkata, tetapi Anda tahu bagaimana hal-hal ini berkembang secara organik, dan apa alternatifnya - mengganti nama semua kelas untuk menyertakan namespace? Refactoring utama segalanya?
Bagaimanapun, ada beberapa tempat di mana proyek yang mereferensikan semua perpustakaan yang berbeda ini diperlukan untuk menggunakan beberapa versi kelas.
Dengan
using
langsung di atas, ini adalah rasa sakit yang hebat di pantat, ReSharper akan melakukan hal-hal aneh untuk mencoba dan membuatnya bekerja, menulis ulangusing
arahan dengan cepat, Anda akan mendapatkan Pelanggan-tidak-bisa-dilemparkan-sebagai- Kesalahan gaya pelanggan dan tidak tahu jenis mana yang benar.Jadi, setidaknya memiliki namespace parsial,
atau
sangat meningkatkan keterbacaan kode dan membuatnya eksplisit objek yang Anda inginkan.
Itu bukan standar pengkodean, itu bukan namespace lengkap, dan itu tidak diterapkan ke semua kelas sebagai standar.
sumber
Tidak ada gunanya menjadi terlalu bertele-tele atau terlalu pendek: seseorang harus menemukan tengah emas dalam cukup rinci untuk mencegah bug halus, sambil menghindari untuk menulis terlalu banyak kode.
Dalam C #, contohnya adalah nama-nama argumen. Saya mengalami beberapa kali masalah di mana saya menghabiskan berjam-jam mencari solusi, sementara gaya penulisan yang lebih verbal dapat mencegah bug di tempat pertama. Masalahnya terdiri dari kesalahan dalam urutan argumen. Misalnya, apakah itu cocok untuk Anda?
Pada pandangan pertama, itu terlihat baik-baik saja, tetapi ada bug. Tanda tangan konstruktor pengecualian adalah:
Memperhatikan urutan argumen?
Dengan mengadopsi gaya yang lebih verbose di mana nama argumen ditentukan setiap kali metode menerima dua atau lebih argumen dari jenis yang sama , kami mencegah kesalahan terjadi lagi, dan karenanya:
jelas lebih panjang untuk ditulis, tetapi menghasilkan lebih sedikit waktu terbuang untuk debugging.
Didorong ke ekstrem, orang bisa memaksa untuk menggunakan argumen bernama di mana-mana , termasuk dalam metode seperti di
doSomething(int, string)
mana tidak ada cara untuk mencampur urutan parameter. Ini mungkin akan membahayakan proyek dalam jangka panjang, menghasilkan lebih banyak kode tanpa manfaat mencegah bug yang saya jelaskan di atas.Dalam kasus Anda, motivasi di balik “Tidak ada
using
” aturan adalah bahwa ia harus membuat lebih sulit untuk menggunakan tipe yang salah, sepertiMyCompany.Something.List<T>
vsSystem.Collections.Generic.List<T>
.Secara pribadi, saya akan menghindari aturan seperti itu karena, IMHO, biaya sulit untuk membaca kode jauh di atas manfaat dari risiko yang sedikit berkurang dari penyalahgunaan jenis yang salah, tetapi setidaknya, ada alasan yang sah untuk aturan ini.
sumber
paramName
denganInvokerParameterName
atribut dan mengeluarkan peringatan jika tidak ada parameter seperti itu.SomeBusiness.Something.DoStuff(string name, string description)
? Tidak ada alat yang cukup pintar untuk memahami apa itu nama dan apa itu deskripsi.Namespaces memberi kode struktur hierarkis, memungkinkan untuk nama yang lebih pendek.
Jika Anda mengizinkan kata kunci "menggunakan", ada serangkaian acara ...
(karena mereka menyertakan setiap namespace yang mungkin mereka inginkan)
Jadi untuk menghindari risiko, semua orang mulai menggunakan nama yang sangat panjang:
Situasi meningkat ...
Saya telah melihat ini terjadi, sehingga dapat bersimpati dengan perusahaan yang melarang "menggunakan".
sumber
using
adalah opsi nuklir. Alias Namespace dan kualifikasi parsial lebih disukai.Masalahnya
using
adalah bahwa itu secara ajaib menambahkan ke namespace tanpa pernyataan eksplisit. Ini jauh lebih dari masalah bagi programmer pemeliharaan yang menemukan sesuatu sepertiList<>
dan tanpa terbiasa dengan domain, tidak tahuusing
klausa mana yang telah memperkenalkannya.Masalah serupa terjadi di Jawa jika seseorang menulis
import Java.util.*;
daripadaimport Java.util.List;
misalnya; deklarasi terakhir mendokumentasikan nama apa yang telah diperkenalkan sehingga ketikaList<>
muncul kemudian di sumbernya, asalnya diketahui dariimport
deklarasi.sumber