Menekan peringatan "tidak pernah digunakan" dan "tidak pernah ditetapkan ke" di C #

107

Saya memiliki file HTTPSystemDefinitions.cs dalam proyek C # yang pada dasarnya menjelaskan ISAPI windows yang lebih lama untuk dikonsumsi oleh kode yang dikelola.

Ini termasuk seluruh Struktur yang relevan dengan ISAPI tidak semua atau yang dikonsumsi oleh kode. Saat kompilasi, semua anggota lapangan dari struktur ini menyebabkan peringatan seperti berikut: -

Bidang Peringatan 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' tidak pernah ditetapkan, dan akan selalu memiliki nilai default null

atau

Peringatan Bidang 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' tidak pernah digunakan

Bisakah ini dinonaktifkan dengan #pragma warning disable? Jika demikian, apa angka kesalahan yang sesuai? Jika tidak, apakah ada hal lain yang bisa saya lakukan? Ingatlah bahwa saya hanya melakukan apa ini untuk file ini, yang penting saya mendapatkan peringatan seperti ini datang dari file lain.

Edit

Contoh struct: -

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader;
    internal SetHeaderDelegate SetHeader;
    internal AddHeaderDelegate AddHeader;

    UInt32  HttpStatus;               // New in 4.0, status for SEND_RESPONSE
    UInt32  dwReserved;               // New in 4.0
}
AnthonyWJones
sumber
Dapatkah Anda menunjukkan deklarasi bidang tersebut, atau lebih tepatnya, struct tempat mereka berada? yaitu. berikan contoh.
Lasse V. Karlsen
11
Jika ini adalah definisi interop, biasanya Anda akan [StructLayout(LayoutKind.Sequential)]memastikan tata letak memori sudah benar (dalam implementasi saat ini bahkan tanpa atribut ini, tetapi AFAIK tidak dijamin). Jika saya ingat dengan benar, kompilator C # mendeteksi keberadaan atribut ini dan secara otomatis menyembunyikan peringatan tersebut karena ia tahu bahwa bidang harus ada di sana untuk interop. (Saya bisa saja salah tentang ini, karenanya memposting sebagai komentar, bukan jawaban).
Greg Beech
@Greg: Itu info berguna yang akan saya selidiki. Saya lebih suka peringatan tidak dibuat daripada menyembunyikannya.
AnthonyWJones
1
1 untuk digunakan StructLayout. Tampaknya lebih bersih daripada menekan peringatan itu sendiri.
Deanna
@GregBeech Anda benar! Itu masih berlaku untuk proyek .NET Standard di VS2017.
zwcloud

Jawaban:

195

Ya, ini bisa ditekan.

Biasanya, saya menentang untuk menyembunyikan peringatan, tetapi dalam kasus ini, struct yang digunakan untuk interop benar-benar membutuhkan beberapa bidang untuk ada, meskipun Anda tidak pernah bermaksud (atau dapat) menggunakannya, jadi dalam hal ini saya pikir itu harus dibenarkan .

Biasanya, untuk menyembunyikan kedua peringatan tersebut, Anda akan memperbaiki kode yang melanggar. Yang pertama ("... tidak pernah digunakan") biasanya merupakan kode-bau sisa dari versi kode sebelumnya. Mungkin kode telah dihapus, tetapi bidang tertinggal.

Yang kedua biasanya merupakan kode-bau untuk bidang yang salah digunakan. Misalnya, Anda mungkin salah menulis nilai baru sebuah properti kembali ke properti itu sendiri, tidak pernah menulis ke bidang backing.


Untuk menyembunyikan peringatan untuk " Bidang XYZ tidak pernah digunakan ", Anda melakukan ini:

#pragma warning disable 0169
... field declaration
#pragma warning restore 0169

Untuk menyembunyikan peringatan untuk " Bidang XYZ tidak pernah ditetapkan, dan akan selalu memiliki nilai default XX ", Anda melakukan ini:

#pragma warning disable 0649
... field declaration
#pragma warning restore 0649

Untuk menemukan sendiri nomor peringatan tersebut (yaitu, bagaimana saya tahu cara menggunakan 0169 dan 0649), Anda melakukan ini:

  • Kompilasi kode seperti biasa, ini akan menambahkan beberapa peringatan ke daftar kesalahan Anda di Visual Studio
  • Beralih ke jendela Output, dan Build output, dan cari peringatan yang sama
  • Salin kode peringatan 4 digit dari pesan yang relevan, yang akan terlihat seperti ini:

    C: \ Dev \ VS.NET \ ConsoleApplication19 \ ConsoleApplication19 \ Program.cs (10,28): peringatan CS 0649 : Bidang 'ConsoleApplication19.Program.dwReserved' tidak pernah ditetapkan, dan akan selalu memiliki nilai default 0


Peringatan : Sesuai komentar oleh @Jon Hanna , mungkin ada beberapa peringatan untuk hal ini, bagi para penemu pertanyaan dan jawaban ini di masa mendatang.

  • Pertama, dan terpenting, tindakan menekan peringatan mirip dengan menelan pil untuk sakit kepala. Tentu, terkadang ini adalah hal yang benar untuk dilakukan, tetapi ini bukan solusi yang mencakup semua. Terkadang, sakit kepala adalah gejala nyata yang tidak boleh Anda tutupi, sama dengan peringatan. Itu selalu terbaik untuk mencoba menangani peringatan dengan memperbaiki penyebabnya, daripada hanya menghapusnya secara membabi buta dari keluaran build.
  • Karena itu, jika Anda perlu menekan peringatan, ikuti pola yang saya jelaskan di atas. Baris kode pertama #pragma warning disable XYZK,, menonaktifkan peringatan untuk sisa file itu , atau setidaknya sampai yang sesuai #pragma warning restore XYZKditemukan. Minimalkan jumlah baris tempat Anda menonaktifkan peringatan ini. Pola di atas menonaktifkan peringatan hanya untuk satu baris.
  • Juga, seperti yang disebutkan Jon, komentar tentang mengapa Anda melakukan ini adalah ide yang bagus. Menonaktifkan peringatan jelas merupakan kode-bau ketika dilakukan tanpa sebab, dan komentar akan mencegah pengelola di masa depan menghabiskan waktu bertanya-tanya mengapa Anda melakukannya, atau bahkan dengan menghapusnya dan mencoba memperbaiki peringatan.
Lasse V. Karlsen
sumber
9
Saya akan merekomendasikan lebih jauh ke jawaban di atas, bahwa ruang lingkup penonaktifan sekecil mungkin (untuk menghindari penonaktifan di suatu tempat yang berguna) dan untuk selalu menyertai penonaktifan dengan komentar mengapa Anda menonaktifkan, misalnya //exists for interopdi kasus ini.
Jon Hanna
Terima kasih banyak. Ini adalah pilihan yang aneh bahwa VS tidak menyertakan kolom untuk angka-angka ini di jendela Daftar Kesalahan.
AnthonyWJones
2
Seperti yang dikatakan Jon, mengomentari "mengapa" itu sangat penting. Selain itu, saya biasanya menambahkan setidaknya sebagian teks dari pesan peringatan ke komentar misalnya // Suppress "tidak pernah ditugaskan ke ..." peringatan. Simpan pengelola masa depan dari gangguan karena harus mencari kode peringatan - lagipula, itu bisa jadi Anda!
Tom Bushell
1
Ini tidak segera jelas tetapi Anda dapat menggunakan Temukan di jendela Output melalui CTRL + F, ketik "peringatan", klik "Temukan Semua" dan dapatkan setiap peringatan dengan cepat, dengan nomor peringatan ditampilkan. Yang mengatakan [StructLayout(LayoutKind.Sequential)]atribut menangani interop jauh lebih baik sesuai komentar Greg Beech tentang pertanyaan itu.
Ryan Buddicom
2
Berkomentar untuk mengatakan bahwa untuk pengguna Unity3D, nomor peringatan adalah 0414 untuk bidang pribadi dan 0219 untuk variabel lokal, bukan 169 (yang memunculkan peringatan tentang tidak dapat memulihkan peringatan sebagai gantinya).
Draco18s tidak lagi mempercayai SE
14

"Solusi" lain untuk memperbaiki peringatan ini adalah dengan membuat struct public. Peringatan tidak dikeluarkan karena kompilator tidak dapat mengetahui apakah bidang sedang digunakan (ditetapkan) di luar rakitan.

Yang mengatakan, komponen "interop" biasanya tidak publik, melainkan internalatau private.

floele
sumber
2
Bagus, ini tidak menyembunyikan peringatan ... tapi menetapkan seperti structyang publiclebih mungkin untuk menjadi kesalahan daripada peringatan kita mencoba untuk menutupi. (Anda mungkin tidak boleh mengekspos tipe yang digunakan untuk implementasi internal dan tipe dengan field publik yang mungkin tidak termasuk dalam API publik). Hanya untuk memperkuat saran Anda bahwa tipe seperti itu harus "lebih baik internalatau private" ;-).
binki
terima kasih yang luar biasa - inilah yang saya butuhkan. Saya menggunakan JsonConvert.DeserializeObjectdan saya melakukan deserialisasi ke kelas publik yang semua propertinya terekspos sehingga saya tahu apa yang akan dikembalikan. Hanya menjadikannya kelas publik yang kosong dengan semua string publik adalah kode pendek yang bagus dan sekarang tidak ada lagi peringatan. Mungkin menggunakan kelas dinamis akan lebih baik karena Anda tidak perlu secara eksplisit menyatakan apa yang ada di dalam array, tetapi saya pikir ini akan menjadi referensi yang bagus bagi siapa pun yang berharap untuk menggunakan objek tersebut.
pengguna1274820
6

Saya mendapat VS untuk menghasilkan kerangka implementasi System.ComponentModel.INotifyPropertyChangeddan kejadian diimplementasikan sebagai bidang yang memicu peringatan CS0067.

Sebagai alternatif dari solusi yang diberikan dalam jawaban yang diterima, saya mengubah bidang menjadi properti dan peringatan menghilang .

Ini masuk akal karena gula sintaks deklarasi properti dikompilasi ke dalam bidang plus metode pengambil dan / atau penyetel (tambahkan / hapus dalam kasus saya) yang mereferensikan bidang tersebut. Ini memenuhi kompilator dan peringatan tidak dimunculkan:

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader {get;set;}
    internal SetHeaderDelegate SetHeader { get; set; }
    internal AddHeaderDelegate AddHeader { get; set; }

    UInt32 HttpStatus { get; set; }               // New in 4.0, status for SEND_RESPONSE
    UInt32 dwReserved { get; set; }               // New in 4.0
}
Pencho Ilchev
sumber
Solusi Anda jauh lebih baik daripada menonaktifkan peringatan, tetapi dapat mengganggu beberapa atribut khusus bidang, misalnya MarshalAsAttribute.
HuBeZa
1
Info: Field privat sebenarnya yang dibuat dalam situasi ini mungkin memiliki nama "aneh" seperti <GetHeader>k__BackingField, bergantung pada detail implementasi dari compiler C # yang digunakan.
Jeppe Stig Nielsen
1

Pengguna C / C ++ harus (void)var;menyembunyikan peringatan variabel yang tidak digunakan. Saya baru saja menemukan Anda juga dapat menekan peringatan variabel yang tidak digunakan di C # dengan operator bitwise:

        uint test1 = 12345;
        test1 |= 0; // test1 is still 12345

        bool test2 = true;
        test2 &= false; // test2 is now false

Kedua ekspresi tidak menghasilkan peringatan variabel yang tidak digunakan di kompiler VS2010 C # 4.0 dan Mono 2.10.

ceztko
sumber
4
Bekerja untuk uint, tetapi tidak untuk jenis lain, seperti Exception. Apakah Anda mengetahui trik umum yang setara dengan C / C ++ var;?
manuell
1
@manuell halo dari masa depan! Anda dapat menggunakan error.ToString();untuk variabel tipeException
Sv443
Terima kasih mulai sekarang. Trik itu menambahkan kode nyata saat runtime, bukan?
manuell