Apakah praktik yang buruk untuk menggunakan kembali parameter metode?


12

Ada saat-saat ketika saya perlu mengubah nilai yang diteruskan ke metode dari dalam metode itu sendiri. Contohnya akan membersihkan string seperti metode ini di sini:

void SanitizeName(string Name)
{
    Name = Name.ToUpper();

    //now do something here with name
}

Ini murni tidak berbahaya karena Nameargumen tidak disahkan oleh referensi. Namun, jika, karena alasan tertentu, pengembang di masa depan memutuskan untuk memiliki semua nilai yang diteruskan oleh ref, sanitasi dari string akan memengaruhi nilai di luar metode yang dapat memiliki hasil yang merusak.

Oleh karena itu, alih-alih menugaskan kembali argumen itu sendiri, saya selalu membuat salinan lokal seperti:

void SanitizeName(string Name)
{
    var SanitizedName = Name.ToUpper();

    //now do something here with name
}

Ini memastikan bahwa mengubah nilai yang diteruskan tidak akan memengaruhi kejadian di luar metode, tetapi saya bertanya-tanya apakah saya terlalu paranoid tentang hal ini.


1
Ya, itu praktik buruk; dan tidak, itu tidak berbahaya. Baris Name = Name.ToUpper();membuat kode lebih sulit untuk diikuti di kepala Anda sebagai nilai Nameperubahan. Contoh kedua Anda tidak hanya lebih banyak bukti masa depan, lebih mudah untuk alasan apa yang dilakukannya
David Arno

2
Tapi bagaimana dengan itu if (param == NULL) param = default_value;?
aragaer

Saya pikir itu tidak semudah ya / tidak.
MrSmith42

3
Jika "seorang pengembang di masa depan memutuskan untuk memiliki semua nilai yang diteruskan oleh ref" , saya mungkin akan berdebat dengan dev itu, menggunakan kembali parameter yang terlibat atau tidak ;-) Jujur, ketika seseorang memutuskan untuk memberikan nilai by refyang tidak lulus itu cara sebelumnya, dan mengubah akses lokal ke akses non-lokal untuk beberapa alasan, ia selalu memeriksa konsekuensinya dengan hati-hati.
Doc Brown

2
Saya terutama bekerja dalam paradigma di mana kita tidak pernah menetapkan ulang variabel apa pun . Pernah. Lucu membayangkan seseorang yang berjuang dengan apakah mereka harus menugaskan sekelompok kecil variabel dan kemudian tidak khawatir tentang menjadi liar dengan yang lain.
Karl Bielefeldt

Jawaban:


10

Saya pikir itu tergantung pada konvensi pengkodean Anda di proyek Anda.

Saya pribadi membiarkan eclipse secara otomatis menambahkan finalkata kunci ke setiap variabel dan parameter. Dengan cara ini Anda melihat pada pandangan pertama jika suatu parameter digunakan kembali.

Dalam proyek di pekerjaan saya, kami tidak merekomendasikan untuk menggunakan kembali parameter, tetapi jika Anda hanya ingin memanggil misalnya .trim()atau menetapkan default dalam suatu nullkasus, kami menggunakan kembali sebagian besar parameter, karena memperkenalkan variabel baru dalam kasus seperti itu kurang dapat dibaca daripada penggunaan kembali parameter.

Anda seharusnya benar-benar tidak menggunakan kembali parameter untuk menyimpan konten yang sangat berbeda karena namanya tidak lagi merujuk ke kontennya. Tapi ini berlaku untuk setiap pergantian variabel dan tidak terbatas pada parameter.

Jadi, berkumpullah bersama tim Anda dan rumuskan konvensi pengkodean yang membahas masalah ini.


0

Jika Anda menggunakan penganalisa kode statis untuk tujuan keamanan, mungkin akan membingungkan, dan berpikir Anda belum memvalidasi atau membersihkan variabel parameter input sebelum digunakan. Jika Anda menggunakan Namedalam kueri SQL, misalnya, itu mungkin mengklaim kerentanan injeksi SQL, yang akan menghabiskan waktu Anda untuk menjelaskannya. Itu buruk. Di sisi lain, menggunakan variabel yang diberi nama berbeda untuk input yang disanitasi, tanpa benar-benar membersihkan input, adalah cara cepat untuk menenangkan penganalisa kode yang naif (temuan kerentanan negatif palsu).


Anda juga dapat dalam sebagian besar kasus menggunakan semacam anotasi atau komentar khusus untuk menunjukkan kepada penganalisa kode bahwa ini dimaksudkan dan bukan risiko tanpa disadari.
MrSmith42

0

Jawabannya tergantung 100% pada siapa yang akan membaca kode Anda. Gaya apa yang menurut mereka paling membantu?

Saya telah menemukan kasus yang paling umum adalah bahwa seseorang menghindari penugasan kembali nilai ke argumen fungsi karena terlalu banyak pengembang yang memiliki model mental tentang cara kerja pemanggilan fungsi yang berasumsi bahwa Anda tidak pernah melakukan ini. Masalah ini dapat diperburuk oleh para debugger yang mencetak nilai-nilai argumen yang Anda panggil setiap fungsi. Informasi ini secara teknis tidak benar jika Anda mengedit argumen, dan itu dapat menyebabkan beberapa frustrasi aneh.

Yang sedang berkata, model mental berubah. Dalam lingkungan pengembangan khusus Anda, mungkin diinginkan untuk namemenjadi "representasi terbaik dari nama pada saat ini." Mungkin diinginkan untuk lebih eksplisit menghubungkan variabel yang sedang Anda kerjakan dengan argumen mereka, meskipun Anda telah melakukan beberapa modifikasi pada nilai-nilai mereka di sepanjang jalan. Bahkan mungkin ada keuntungan runtime yang substansial untuk menggunakan kembali beberapa variabel tertentu daripada membuat lebih banyak objek besar. Lagi pula, ketika Anda bekerja dengan string 4GB, alangkah baiknya untuk meminimalkan jumlah salinan tambahan yang harus Anda buat!


-1

Saya memiliki masalah yang sangat berbeda dengan contoh kode Anda:

Nama metode Anda adalah SanitizeName. Dalam hal ini, saya berharap itu membersihkan nama ; karena itulah yang Anda katakan kepada pembaca tentang fungsi Anda.

Satu- satunya hal yang harus Anda lakukan adalah membersihkan nama yang diberikan . Tanpa membaca kode Anda, saya berharap yang berikut:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

Tapi Anda menyiratkan, bahwa metode Anda melakukan sedikit lebih dari sanitizng saja . Itu bau kode dan harus dihindari.

Pertanyaan Anda bukan tentang: Apakah praktik yang buruk untuk menggunakan kembali parameter metode? Lebih dari itu: apakah efek samping dan perilaku yang tidak diketahui merupakan praktik buruk?

Jawabannya jelas: ya!

Ini murni tidak berbahaya karena argumen Nama tidak disahkan oleh referensi. Namun, jika, karena alasan tertentu, pengembang di masa depan memutuskan untuk memiliki semua nilai yang diteruskan oleh ref, setiap sanitasi string akan mempengaruhi nilai di luar metode yang dapat memiliki hasil yang merusak

Anda menyesatkan pembaca Anda dengan tidak mengembalikan apa pun. Nama metode Anda dengan jelas menunjukkan, bahwa Anda melakukan sesuatu Name. Jadi, kemana hasilnya harus pergi? Dengan fungsi Anda tanda tangan voiddibaca saya gunakan Nametetapi tidak ada salahnya untuk id, atau memberi tahu Anda tentang hasilnya (secara eksplisit). Mungkin ada pengecualian yang dilemparkan, mungkin tidak; tetapi Nametidak diubah . Ini adalah kebalikan semantik dari nama metode Anda.

Masalahnya kurang penggunaan kembali daripada efek samping . Untuk mencegah efek samping, jangan gunakan kembali variabel. Jika Anda tidak memiliki efek samping, tidak ada masalah.


4
-1 Ini tidak menjawab pertanyaan awal. Kode yang disediakan hanyalah kode sampel untuk menunjukkan pertanyaan yang ada. Jawab pertanyaan, alih-alih "menyerang" / meninjau kode contoh yang disediakan.
Niklas H

1
@ NiklasH Ini menjawab pertanyaan dengan sempurna: jika Anda memanipulasi parameter di dalam fungsi dan sebagai TO disebutkan Anda tidak sengaja bekerja dengan referensi, bukan salinan, ini menyebabkan efek samping (seperti yang saya katakan) dan ini buruk. Untuk mencegah hal itu mengindikasikan bahwa Anda akan mengubah variabel dengan memilih nama metode dengan hati-hati (pikirkan Ruby '!') Dan / atau memilih jenis pengembalian. Jika Anda tidak mengubah variabel, hanya bekerja dengan salinan.
Thomas Junk
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.