Saya melihat pola kode berikut di semua tempat di basis kode perusahaan saya (aplikasi .NET 3.5):
bool Foo(int barID, out Baz bazObject) {
try {
// do stuff
bazObject = someResponseObject;
return true;
}
catch (Exception ex) {
// log error
return false;
}
}
// calling code
BazObject baz = new BazObject();
fooObject.Foo(barID, out baz);
if (baz != null) {
// do stuff with baz
}
Saya mencoba membungkus kepala saya di sekitar mengapa Anda akan melakukan ini daripada memiliki Foo
metode hanya mengambil ID dan mengembalikan Baz
objek, bukannya mengembalikan nilai yang tidak digunakan dan memiliki objek yang sebenarnya menjadi parameter ref atau output.
Apakah ada beberapa manfaat tersembunyi dari gaya pengkodean ini yang saya lewatkan?
c#
code-quality
coding-style
Wayne Molina
sumber
sumber
baz
menjadinull
dan kembalibool
makhlukfalse
yang tidak setara.new BazObject()
tidak pernahnull
, jadi kecualibazObject
diperbarui sebelumException
dilemparkanFoo
, ketikafalse
dikembalikanbaz
tidak akan pernahnull
. Ini akan membantu sangat jika spesifikasi untukFoo
yang tersedia. Sebenarnya, ini mungkin masalah paling serius yang ditunjukkan oleh kode ini.Jawaban:
Anda biasanya menggunakan pola itu sehingga Anda dapat menulis kode seperti ini:
misalnya digunakan di CLR untuk TryGetValue di kelas kamus misalnya. Itu menghindari beberapa redundansi tetapi parameter out dan ref selalu tampak agak berantakan bagi saya
sumber
Ini adalah kode gaya C lama, sebelum ada pengecualian. Nilai kembali menunjukkan apakah metode itu berhasil atau tidak, dan jika itu, parameter akan diisi dengan hasilnya.
Di .net kami memiliki pengecualian untuk tujuan itu. Seharusnya tidak ada alasan untuk mengikuti pola ini.
[Sunting] Jelas ada implikasi kinerja dalam penanganan pengecualian. Mungkin itu ada hubungannya dengan itu. Namun, dalam cuplikan kode itu sudah ada pengecualian. Akan lebih bersih untuk membiarkannya naik tumpukan sampai tertangkap di tempat yang lebih tepat.
sumber
if (baz.Select())
tetapi lebih sering nilai pengembaliannya dibuang begitu saja dan nilainya diperiksa terhadap null atau properti tertentu.Diberikan potongan kode itu terlihat benar-benar tidak berguna. Bagi saya pola kode awal akan menyarankan bahwa null untuk BazObject akan menjadi kasus yang dapat diterima dan pengembalian bool adalah ukuran menentukan kasus gagal dengan aman. Jika kode berikut adalah:
Ini akan lebih masuk akal bagi saya untuk melakukannya dengan cara ini. Mungkin ini adalah metode yang seseorang sebelum Anda gunakan untuk menjamin bahwa baz dilewatkan dengan referensi tanpa memahami bagaimana sebenarnya parameter objek bekerja di C #.
sumber
Terkadang pola ini berguna ketika Anda, si penelepon, tidak seharusnya peduli apakah tipe yang dikembalikan adalah tipe referensi atau nilai. Jika Anda memanggil metode seperti itu untuk mengambil tipe nilai, tipe nilai itu akan membutuhkan nilai yang tidak valid (mis. Double.NaN), atau Anda perlu cara lain untuk menentukan kesuksesan.
sumber
Idenya adalah mengembalikan nilai yang menunjukkan apakah proses berhasil, memungkinkan kode seperti ini:
Jika objek tidak boleh nol (yang muncul benar dalam contoh Anda), lebih baik dilakukan sebagai berikut:
Jika objek bisa nol, pengecualian adalah cara untuk pergi:
Ini adalah pola umum yang digunakan dalam C, di mana tidak ada pengecualian. Ini memungkinkan fungsi untuk mengembalikan kondisi kesalahan. Pengecualian umumnya merupakan solusi yang jauh lebih bersih.
sumber