C # - Apa yang dilakukan metode Assert ()? Apakah masih bermanfaat?

156

Saya men-debug dengan breakpoints dan saya menyadari panggilan tegas? Saya pikir itu hanya untuk tes unit. Apa fungsinya lebih dari breakpoint? Karena saya bisa breakpoint, mengapa saya harus menggunakan Assert?

Pokus
sumber
9
Omong-omong, jika Anda tertarik untuk menegaskan Anda harus mempelajari kontrak kode .
MasterMastic
Kemungkinan duplikat stackoverflow.com/questions/129120/…
Michael Freidgeim

Jawaban:

200

Dalam kompilasi debug, Assertambil dalam kondisi Boolean sebagai parameter, dan tampilkan dialog kesalahan jika kondisinya salah. Program berjalan tanpa gangguan jika kondisinya benar.

Jika Anda mengkompilasi dalam Release, semua Debug.Assertsecara otomatis ditinggalkan.

Patrick Desjardins
sumber
12
bagaimana saya bisa mendapatkan perilaku Debug.Assert yang sama dalam mode Rilis?
Hamish Grubijan
15
Trace.Assert untuk mode rilis rupanya ref: msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell
8
@ HamishGrubijan Dan mengapa Anda ingin Debug.Assertdalam mode rilis?
Camilo Martin
25
IMO, menghilangkan pernyataan dari kode rilis seperti melakukan latihan sekoci saat merapat dan kemudian meninggalkan sekoci saat Anda berlayar. :)
chrisd
113
Asserts bukan sekoci, mereka adalah sistem pendeteksian gunung es. Karena pengguna tidak mengarahkan kapal, pernyataan dalam kode rilis hanya memberitahu mereka bahwa mereka sudah ditakdirkan; itu tidak membiarkan mereka menghindari gunung es.
Stefan
97

Dari Kode Selesai

8 Pemrograman Defensif

8.2 Pernyataan

Pernyataan adalah kode yang digunakan selama pengembangan - biasanya rutin atau makro - yang memungkinkan program untuk memeriksa dirinya sendiri saat dijalankan. Ketika pernyataan benar, itu berarti semuanya beroperasi seperti yang diharapkan. Ketika itu salah, itu berarti telah mendeteksi kesalahan tak terduga dalam kode. Misalnya, jika sistem mengasumsikan bahwa file informasi pelanggan tidak akan pernah memiliki lebih dari 50.000 catatan, program mungkin berisi pernyataan bahwa jumlah catatan kurang dari atau sama dengan 50.000. Selama jumlah catatan kurang dari atau sama dengan 50.000, pernyataan itu akan diam. Namun, jika menemukan lebih dari 50.000 catatan, maka akan "menyatakan" dengan keras bahwa ada kesalahan dalam program.

Pernyataan sangat berguna dalam program besar, rumit dan dalam program keandalan tinggi. Mereka memungkinkan pemrogram untuk lebih cepat mengeluarkan asumsi antarmuka yang tidak cocok, kesalahan yang muncul ketika kode dimodifikasi, dan sebagainya.

Penegasan biasanya membutuhkan dua argumen: ekspresi boolean yang menggambarkan asumsi yang seharusnya benar dan pesan untuk ditampilkan jika tidak.

(...)

Biasanya, Anda tidak ingin pengguna melihat pesan pernyataan dalam kode produksi; pernyataan terutama untuk digunakan selama pengembangan dan pemeliharaan. Pernyataan biasanya dikompilasi ke dalam kode pada waktu pengembangan dan dikompilasi keluar dari kode untuk produksi. Selama pengembangan, pernyataan menghilangkan asumsi kontradiktif, kondisi yang tidak terduga, nilai buruk diteruskan ke rutinitas, dan sebagainya. Selama produksi, mereka dikompilasi dari kode sehingga pernyataan tidak menurunkan kinerja sistem.

juan
sumber
2
Buku tersebut, Writing Solid Code, juga memiliki diskusi hebat tentang penggunaan tegas. Mereka adalah alat debugging yang hebat!
zooropa
39

Anda harus menggunakannya untuk saat-saat ketika Anda tidak ingin harus breakpoint setiap baris kecil kode untuk memeriksa variabel, tetapi Anda ingin mendapatkan semacam umpan balik jika situasi tertentu hadir, misalnya:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");
thelsdj
sumber
Jika saya menambahkan baris kode yang serupa dengan kode Anda di atas, menjalankan program saya memberikan kesalahan berikut: "error CS0103: Nama 'Debug' tidak ada dalam konteks saat ini". Apakah saya perlu menggunakan pernyataan untuk membuatnya bekerja?
Josh Desmond
4
@JoshDesmondSystem.Diagnostics
Sinjai
16

Assert juga memberi Anda kesempatan lain untuk tertawa pada keterampilan desain UI Microsoft. Maksud saya: dialog dengan tiga tombol Batalkan, Coba Lagi, Abaikan, dan penjelasan tentang bagaimana menafsirkannya di bilah judul!

Joe
sumber
3
Batalkan / Coba Lagi / Abaikan itu klasik! Apakah itu pernyataan yang menyebabkan Windows 3.1 untuk menampilkan ini sepanjang waktu?
devlord
Pada dasarnya itu karena ia menggunakan MessageBox, yang seperti yang Anda katakan tanggal kembali ke Windows 3.1, dan hanya memiliki label tombol yang telah ditentukan. Jadi Anda bisa mengerti mengapa peretasan terjadi, tetapi tidak mengapa peretasan itu masih ada di tahun 2008!
Joe
4
@ Jo. Ini adalah sesuatu yang seharusnya hanya dilihat oleh pengembang bukan pengguna akhir sehingga memperbarui itu mungkin item prioritas yang sangat rendah. Jika itu mengganggu Anda dapat memodifikasi koleksi Debug.Listeners atau Trace.Listeners untuk mengganti penangan default dengan yang melakukan apa pun yang Anda inginkan.
Dan Is Fiddling By Firelight
5
Dan sekarang tahun 2019 dan kotak / tombol dialog yang sama masih ada di sini!
Bouke
10

Assert memungkinkan Anda untuk menegaskan suatu kondisi (pos atau pra) berlaku dalam kode Anda. Ini adalah cara mendokumentasikan niat Anda dan meminta debugger memberi tahu Anda dialog jika niat Anda tidak terpenuhi.

Tidak seperti breakpoint, Assert sesuai dengan kode Anda dan dapat digunakan untuk menambahkan detail tambahan tentang niat Anda.

Jeff Yates
sumber
10

Assert dapat membantu Anda memberikan perilaku pengiriman pesan yang terpisah antara pengujian dan rilis. Sebagai contoh,

Debug.Assert(x > 2)

hanya akan memicu jeda jika Anda menjalankan "debug" build, bukan rilis build. Ada contoh lengkap dari perilaku ini di sini

Ryan
sumber
10

Pertama-tama Assert()metode tersedia untuk Tracedan Debugkelas.
Debug.Assert()hanya mengeksekusi dalam mode Debug.
Trace.Assert()sedang dieksekusi dalam mode Debug dan Rilis.

Berikut ini sebuah contoh:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Jalankan kode ini dalam mode Debug dan kemudian dalam mode Rilis.

masukkan deskripsi gambar di sini

Anda akan melihat bahwa selama mode Debug Debug.Assertpernyataan kode Anda gagal, Anda mendapatkan kotak pesan yang menunjukkan jejak tumpukan aplikasi saat ini. Ini tidak terjadi dalam mode Rilis karena Trace.Assert()kondisinya benar (i == 4).

WriteLine() Metode hanya memberi Anda pilihan untuk mencatat informasi ke output Visual Studio. masukkan deskripsi gambar di sini

Serge Voloshenko
sumber
5

Pernyataan fitur berat dalam Desain dengan Kontrak (DbC) yang seperti yang saya pahami diperkenalkan / didukung oleh Meyer, Bertand. 1997. Contruction Perangkat Lunak Berorientasi Objek.

Fitur penting adalah bahwa mereka tidak boleh menghasilkan efek samping, misalnya Anda dapat menangani pengecualian atau mengambil tindakan yang berbeda dengan pernyataan if (defensive programming).

Pernyataan digunakan untuk memeriksa kondisi sebelum / sesudah kontrak, hubungan klien / pemasok - klien harus memastikan bahwa prasyarat pemasok terpenuhi misalnya. mengirimkan £ 5 dan pemasok harus memastikan bahwa syarat-syarat terpenuhi misalnya. memberikan 12 mawar. (Hanya penjelasan sederhana dari klien / pemasok - dapat menerima lebih sedikit dan memberikan lebih banyak, tetapi tentang Pernyataan). C # juga memperkenalkan Trace.Assert (), yang dapat digunakan untuk kode rilis.

Untuk menjawab pertanyaan ya mereka masih berguna, tetapi dapat menambah kompleksitas + keterbacaan ke kode dan waktu + sulit untuk mempertahankan. Haruskah kita masih menggunakannya? Ya, akankah kita semua menggunakannya? Mungkin tidak, atau tidak sejauh yang dijelaskan Meyer.

(Bahkan kursus OU Java yang saya pelajari tentang teknik ini hanya menunjukkan contoh-contoh sederhana dan kode-kode lainnya di sana tidak menerapkan aturan pernyataan DbC pada sebagian besar kode, tetapi diasumsikan digunakan untuk memastikan kebenaran program!)

Knightlore
sumber
3

Cara saya memikirkannya adalah Debug.Assert adalah cara untuk membuat kontrak tentang bagaimana metode seharusnya dipanggil, dengan fokus pada spesifik tentang nilai-nilai paramter (bukan hanya tipe). Misalnya, jika Anda tidak seharusnya mengirim nol di parameter kedua, Anda menambahkan Assert di sekitar parameter itu untuk memberi tahu konsumen untuk tidak melakukan itu.

Ini mencegah seseorang menggunakan kode Anda dengan cara yang bodoh. Tetapi itu juga memungkinkan cara sederhana untuk melalui produksi dan tidak memberikan pesan buruk kepada pelanggan (dengan asumsi Anda membangun rilis Rilis).

Flory
sumber
6
Penting untuk menunjukkan, bahwa parameter yang tidak valid pada metode publik harus membuang pengecualian argumen. Hanya metode pribadi yang harus memvalidasi input dengan pernyataan. Nilai-nilai yang datang dari luar selalu dicurigai!
Jeffrey L Whitledge