Ada beberapa (sangat jarang) kasus di mana ada risiko:
menggunakan kembali variabel yang tidak dimaksudkan untuk digunakan kembali (lihat contoh 1),
atau menggunakan variabel bukan yang lain, tutup semantik (lihat contoh 2).
Contoh 1:
var data = this.InitializeData();
if (this.IsConsistent(data, this.state))
{
this.ETL.Process(data); // Alters original data in a way it couldn't be used any longer.
}
// ...
foreach (var flow in data.Flows)
{
// This shouldn't happen: given that ETL possibly altered the contents of `data`, it is
// not longer reliable to use `data.Flows`.
}
Contoh 2:
var userSettingsFile = SettingsFiles.LoadForUser();
var appSettingsFile = SettingsFiles.LoadForApp();
if (someCondition)
{
userSettingsFile.Destroy();
}
userSettingsFile.ParseAndApply(); // There is a mistake here: `userSettingsFile` was maybe
// destroyed. It's `appSettingsFile` which should have
// been used instead.
Risiko ini dapat dikurangi dengan memperkenalkan ruang lingkup:
Contoh 1:
// There is no `foreach`, `if` or anything like this before `{`.
{
var data = this.InitializeData();
if (this.IsConsistent(data, this.state))
{
this.ETL.Process(data);
}
}
// ...
// A few lines later, we can't use `data.Flows`, because it doesn't exist in this scope.
Contoh 2:
{
var userSettingsFile = SettingsFiles.LoadForUser();
if (someCondition)
{
userSettingsFile.Destroy();
}
}
{
var appSettingsFile = SettingsFiles.LoadForApp();
// `userSettingsFile` is out of scope. There is no risk to use it instead of
// `appSettingsFile`.
}
Apakah itu terlihat salah? Apakah Anda akan menghindari sintaksis seperti itu? Apakah sulit dipahami oleh pemula?
c#
coding-style
language-features
scope
Arseni Mourzenko
sumber
sumber
Jawaban:
Jika fungsi Anda begitu lama sehingga Anda tidak dapat mengenali efek samping yang tidak diinginkan atau penggunaan kembali variabel secara ilegal, maka sekarang saatnya untuk membaginya dalam fungsi yang lebih kecil - yang membuat ruang lingkup internal tidak ada gunanya.
Untuk mendukung hal ini oleh beberapa pengalaman pribadi: beberapa tahun yang lalu saya mewarisi proyek warisan C ++ dengan ~ 150 ribu baris kode, dan berisi beberapa metode yang menggunakan teknik ini. Dan coba tebak - semua metode itu terlalu panjang. Ketika kami refactored sebagian besar kode itu, metode menjadi lebih kecil dan lebih kecil, dan saya cukup yakin tidak ada metode "ruang lingkup internal" yang tersisa lagi; mereka sama sekali tidak dibutuhkan.
sumber
Jauh lebih mudah bagi pemula (dan programmer mana pun) untuk memikirkan:
daripada memikirkan:
Selain itu, dari sudut pandang pembaca, blok seperti itu tidak memiliki peran yang jelas: menghapusnya tidak berdampak pada eksekusi. Pembaca dapat menggaruk kepalanya mencoba menebak apa yang ingin dicapai oleh pembuat kode.
sumber
Menggunakan ruang lingkup secara teknis benar. Tetapi jika Anda ingin membuat kode Anda lebih mudah dibaca maka Anda harus mengekstrak bagian itu dalam metode lain dan memberikan arti nama lengkap. Dengan cara ini Anda bisa memberi ruang lingkup variabel Anda dan juga memberi nama tugas Anda.
sumber
Saya setuju bahwa menggunakan kembali variabel lebih sering daripada tidak berbau kode. Mungkin kode semacam itu harus di refactored dalam blok-blok yang lebih kecil dan mandiri.
Ada satu skenario khusus, OTOH, di C #, ketika mereka cenderung muncul - yaitu ketika menggunakan konstruksi kasus saklar. Situasi dijelaskan dengan sangat baik dalam: C # Beralih pernyataan dengan / tanpa kurung keriting ... apa bedanya?
sumber