Mengatasi kesalahan dan peringatan untuk delegasi dan penunjuk fungsi

Artikel ini membahas kesalahan dan peringatan pengkompilasi berikut:

  • CS0059: Aksesibilitas tidak konsisten: tipe parameter 'tipe' kurang dapat diakses daripada delegate 'delegate'.
  • CS0123: Tidak ada kelebihan beban untuk 'metode' yang cocok dengan delegasi 'delegasi'.
  • CS0148: Deleget 'deleget' tidak memiliki konstruktor yang valid.
  • CS0410: Tidak ada kelebihan beban untuk 'metode' yang memiliki parameter dan jenis pengembalian yang benar.
  • CS0644: 'class' tidak dapat berasal dari kelas khusus 'class'.
  • CS1599: Tipe pengembalian dari sebuah metode, delegasi, atau penunjuk fungsi tidak dapat berupa 'type'.
  • CS1958: Ekspresi penginisialisasi objek dan koleksi mungkin tidak diterapkan ke ekspresi pembuatan delegasi.
  • CS8755: 'pengubah' tidak dapat digunakan sebagai pengubah pada parameter penunjuk fungsi.
  • CS8756: Penunjuk fungsi 'type' tidak mengambil argumen 'count'.
  • CS8757: Tidak ada kelebihan beban untuk 'metode' yang cocok dengan 'jenis' penunjuk fungsi.
  • CS8758: Ketidakcocokan ref antara 'metode' dan penunjuk fungsi 'type'.
  • CS8759: Tidak dapat membuat penunjuk fungsi untuk 'metode' karena bukan metode statis.
  • CS8786: Konvensi panggilan 'konvensi' tidak kompatibel dengan 'konvensi'.
  • CS8787: Tidak dapat mengonversi grup metode ke penunjuk fungsi. (Apakah Anda kehilangan '&'?)
  • CS8788: Tidak dapat menggunakan metode ekstensi dengan penerima sebagai target operator '&'.
  • CS8789: Jenis lokal yang dideklarasikan dalam pernyataan tetap tidak dapat menjadi jenis penunjuk fungsi.
  • CS8806: Konvensi pemanggilan 'convention' tidak didukung oleh bahasa pemrograman.
  • CS8807: 'spesifikator' bukan spesifikator konvensi pemanggilan yang valid untuk penunjuk fungsi.
  • CS8808: 'pengubah' bukan pengubah tipe pengembalian penunjuk fungsi yang valid. Pengubah yang valid adalah 'ref' dan 'ref readonly'.
  • CS8809: Jenis pengembalian hanya dapat memiliki satu pengubah 'pengubah'.
  • CS8811: Tidak dapat mengonversi kelompok metode 'method' menjadi tipe delegasi 'type'.
  • CS8909: Perbandingan penunjuk fungsi mungkin menghasilkan hasil yang tidak terduga, karena penunjuk ke fungsi yang sama mungkin berbeda.
  • CS8911: Menggunakan jenis penunjuk fungsi dalam konteks ini tidak didukung.

Ketidakcocokan penandatangan fungsi

  • CS0059: Aksesibilitas tidak konsisten: tipe parameter 'tipe' kurang dapat diakses daripada deleget 'delegasi'.
  • CS0123: Tidak ada kelebihan beban untuk 'metode' yang cocok dengan delegasi 'delegasi'.
  • CS0148: Deleget 'delegasi' tidak memiliki konstruktor yang valid.
  • CS0410: Tidak ada kelebihan beban untuk 'metode' yang memiliki parameter dan jenis pengembalian yang benar.

Saat Anda membuat atau menetapkan delegasi, pengkompilasi memverifikasi bahwa tanda tangan metode target cocok dengan deklarasi jenis delegasi. Tanda tangan mencakup jenis parameter, jenis pengembalian, dan aksesibilitas. Untuk aturan lengkapnya, lihat Batasan Delegasi dan Aksesibilitas dalam spesifikasi C#.

  • Ubah semua jenis parameter dalam deklarasi delegasi ke jenis yang setidaknya memiliki tingkat aksesibilitas sama atau lebih tinggi dari delegasi itu sendiri (CS0059). public Delegat tidak dapat mereferensikan tipe dengan aksesibilitas lebih rendah dalam daftar parameternya karena penelpon dari luar assembly tidak dapat menyediakan argumen tersebut. Untuk informasi selengkapnya, lihat Pengubah Akses.
  • Sesuaikan tanda tangan metode atau tanda tangan delegasi sehingga jenis parameter dan jenis pengembalian sama persis (CS0123). Pengkompilasi memerlukan kecocokan tanda tangan yang tepat saat Anda menetapkan metode ke delegate.
  • Verifikasi bahwa delegasi dikompilasi oleh kompilator yang sesuai (CS0148). Kesalahan ini terjadi ketika Anda mengimpor rakitan terkelola yang dibangun oleh pengkompilasi yang menghasilkan konstruktor delegasi yang salah bentuk. Kompilasi ulang rakitan dengan kompilator yang mematuhi standar untuk mengatasi kesalahan.

Catatan

CS0410 tidak lagi diproduksi oleh kompilator C# saat ini. Kondisi yang sama sekarang menghasilkan CS0123 sebagai gantinya. Rakitan lama yang dikompilasi dengan pengkompilasi sebelumnya mungkin masih mereferensikan kode kesalahan ini.

CS0148 adalah diagnostik yang hanya terjadi saat build:

Catatan

Peringatan ini hanya dilaporkan selama operasi Build atau Rebuild eksplisit. Ini tidak muncul ketika sedang mengetik di IDE sebagai bagian dari diagnostik IntelliSense. Ini berarti bahwa jika Anda memperbaiki peringatan dengan menggunakan atau menghapus field tersebut, peringatan mungkin tetap muncul dalam daftar kesalahan sampai Anda membangun ulang proyek.

Mendelegasikan pembatasan jenis

  • CS0644: 'class' tidak dapat berasal dari kelas khusus 'class'.
  • CS1599: Tipe pengembalian metode, delegasi, atau penunjuk fungsi tidak boleh 'tipe'.
  • CS1958: Ekspresi penginisialisasi objek dan koleksi mungkin tidak diterapkan ke ekspresi pembuatan delegasi.

Bahasa C# membatasi bagaimana Anda dapat menggunakan jenis khusus tertentu, termasuk System.Delegate. Untuk aturan lengkap tentang deklarasi delegasi, lihat Delegasi dan Delegasi dalam spesifikasi C#.

  • Hapus kelas dasar eksplisit dan gunakan delegate deklarasi sebagai gantinya (CS0644). Kelas tidak dapat secara eksplisit mewarisi dari System.Delegate, , System.EnumSystem.ValueType, atau System.Array. Pengkompilasi menggunakan jenis ini sebagai kelas dasar implisit. Misalnya, setiap delegate deklarasi secara implisit berasal dari System.Delegate.
  • Ubah jenis pengembalian menjadi jenis yang diizinkan sebagai nilai pengembalian (CS1599). Jenis tertentu dalam pustaka kelas .NET, seperti TypedReference, RuntimeArgumentHandle, dan ArgIterator, tidak dapat digunakan sebagai jenis pengembalian untuk metode, delegasi, atau penunjuk fungsi karena dapat berpotensi mengaktifkan operasi tumpukan yang tidak aman.
  • Hapus kurung kurawal setelah ekspresi pembuatan delegasi (CS1958). Delegasi tidak memiliki anggota yang dapat Anda atur melalui sintaks penginisialisasi objek atau koleksi. Jika Anda memiliki { } setelah ekspresi new DelegateType(method), hapus kurung kurawal.

Ketidakcocokan tanda tangan penunjuk fungsi

  • CS8755: 'pengubah' tidak dapat digunakan sebagai pengubah pada parameter penunjuk fungsi.
  • CS8756: Penunjuk fungsi 'type' tidak mengambil argumen 'count'.
  • CS8757: Tidak ada kelebihan beban untuk 'metode' yang cocok dengan 'jenis' penunjuk fungsi.
  • CS8758: Ketidakcocokan ref antara 'metode' dan penunjuk fungsi 'type'.
  • CS8759: Tidak dapat membuat penunjuk fungsi untuk 'metode' karena bukan metode statis.
  • CS8787: Tidak dapat mengonversi grup metode ke penunjuk fungsi. (Apakah Anda kehilangan '&'?)
  • CS8788: Tidak dapat menggunakan metode ekstensi dengan penerima sebagai target operator '&'.
  • CS8811: Tidak dapat mengonversi grup metode 'metode' ke tipe delegasi 'type'.

Saat Anda menetapkan metode ke penunjuk fungsi dengan menggunakan alamat operator (&), pengkompilasi memeriksa bahwa tanda tangan metode cocok dengan jenis penunjuk fungsi. Untuk aturan lengkap tentang deklarasi dan penggunaan penunjuk fungsi, lihat Penunjuk fungsi dan Kode tidak aman.

  • Hapus pengubah yang tidak didukung dari parameter penunjuk fungsi (CS8755). Parameter penunjuk fungsi hanya mendukung pengubah ref, out, dan in. Pengubah parameter lainnya, seperti params, tidak valid dalam deklarasi jenis penunjuk fungsi.
  • Ubah jumlah argumen di situs panggilan agar sesuai dengan jumlah parameter penunjuk fungsi (CS8756). Jenis penunjuk fungsi mendefinisikan jumlah parameter tetap, dan Anda harus meneruskan argumen sebanyak itu.
  • Sesuaikan tanda tangan metode sehingga jenis parameter, jenis pengembalian, dan jumlah parameternya cocok dengan jenis penunjuk fungsi (CS8757). Tidak seperti delegasi, penunjuk fungsi tidak mendukung konversi implisit antara tanda tangan metode yang kompatibel. Pencocokan harus tepat.
  • Sejajarkan ref, , outatau in pengubah antara parameter metode dan parameter jenis penunjuk fungsi (CS8758). Setiap jenis tipe referensi parameter harus sesuai persis. Parameter ref tidak dapat memenuhi in posisi atau out dalam jenis penunjuk fungsi.
  • Ubah metode target menjadi static (CS8759). Penunjuk fungsi hanya dapat menunjuk ke metode statis karena mewakili alamat fungsi mentah tanpa instans objek terkait.
  • Tambahkan operator & sebelum grup metode saat menetapkannya ke penunjuk fungsi (CS8787). Tidak seperti delegasi, penunjuk fungsi memerlukan alamat operator eksplisit: delegate*<void> ptr = &MyMethod;.
  • Gunakan metode statis alih-alih metode ekstensi dengan penerima (CS8788). Operator & memerlukan referensi metode langsung. Metode ekstensi yang dipanggil pada instans memiliki penerima implisit yang tidak dapat ditangkap dalam penunjuk fungsi.
  • & Hapus operator dan gunakan sintaks delegasi sebagai gantinya, atau ubah jenis target dari delegasi ke penunjuk fungsi (CS8811). Operator & menghasilkan penunjuk fungsi, bukan delegasi. Untuk menetapkan grup metode ke jenis delegasi, hilangkan & dan gunakan sintaks pembuatan delegasi standar.

Konvensi panggilan penunjuk fungsi dan jenis pengembalian

  • CS8786: Konvensi pemanggilan 'konvensi' tidak kompatibel dengan 'konvensi'.
  • CS8806: Konvensi pemanggilan 'konvensi' tidak didukung dalam bahasa ini.
  • CS8807: 'spesifikator' bukan spesifikator konvensi panggilan yang valid untuk penunjuk fungsi.
  • CS8808: 'pengubah' bukan pengubah tipe pengembalian penunjuk fungsi yang valid. Pengubah yang valid adalah 'ref' dan 'ref readonly'.
  • CS8809: Jenis pengembalian hanya dapat memiliki satu pengubah 'modifier'.

Deklarasi penunjuk fungsi mencakup konvensi panggilan dan pengubah jenis pengembalian opsional. Pengkompilasi memvalidasi opsi ini. Untuk aturan lengkapnya, lihat Penunjuk fungsi.

  • Ubah konvensi panggilan metode atau konvensi panggilan jenis penunjuk fungsi sehingga cocok (CS8786). Saat Anda menetapkan metode ke penunjuk fungsi, konvensi panggilan harus kompatibel. Misalnya, metode yang menggunakan Cdecl tidak dapat ditetapkan ke penunjuk fungsi yang dideklarasikan dengan Stdcall.
  • Gunakan konvensi panggilan yang didukung dalam deklarasi penunjuk fungsi (CS8806). Bahasa mendukung managed dan unmanaged. Untuk konvensi tertentu yang tidak dikelola, gunakan unmanaged kata kunci dengan konvensi dalam kurung siku, seperti unmanaged[Cdecl], , unmanaged[Stdcall]unmanaged[Thiscall], atau unmanaged[Fastcall].
  • Ganti penentu yang tidak valid dengan konvensi panggilan yang didukung (CS8807). Gunakan managed, unmanaged, atau unmanaged dengan jenis konvensi panggilan dalam tanda kurung siku (misalnya, unmanaged[Cdecl]).
  • Gunakan hanya ref atau ref readonly sebagai pengubah jenis pengembalian (CS8808). Pengubah lain, seperti out atau in, tidak valid untuk jenis pengembalian penunjuk fungsi.
  • Hapus pengubah jenis pengembalian duplikat sehingga hanya satu ref atau ref readonly muncul (CS8809). Pengkompilasi memungkinkan paling banyak satu pengubah jenis pengembalian pada deklarasi penunjuk fungsi.

Pembatasan penggunaan pointer fungsi

  • CS8789: Jenis lokal yang dideklarasikan dalam pernyataan tetap tidak dapat menjadi jenis penunjuk fungsi.
  • CS8909: Perbandingan penunjuk fungsi mungkin menghasilkan hasil yang tidak terduga, karena penunjuk ke fungsi yang sama mungkin berbeda.
  • CS8911: Menggunakan jenis penunjuk fungsi dalam konteks ini tidak didukung.

Pengkompilasi membatasi bagaimana jenis penunjuk fungsi dapat digunakan dalam konteks tertentu. Untuk aturan lengkapnya, lihat Penunjuk fungsi.

  • Ubah jenis variabel lokal dalam fixed pernyataan menjadi jenis penunjuk data alih-alih jenis penunjuk fungsi (CS8789). Pernyataan fixed menyematkan objek terkelola di dalam memori untuk memungkinkan akses data. Penunjuk fungsi mewakili alamat kode, bukan data, dan tidak dapat disematkan.
  • Hindari membandingkan pointer fungsi untuk kesetaraan (CS8909). Peringatan ini menunjukkan bahwa membandingkan penunjuk fungsi dengan == atau != mungkin menghasilkan hasil yang tidak terduga. Runtime mungkin mengembalikan pointer yang berbeda untuk fungsi yang sama karena detail implementasi seperti thunking atau kompilasi JIT. Untuk menekan peringatan ketika Anda mengonfirmasi bahwa perbandingan disengaja, gunakan #pragma warning disable CS8909.
  • Pindahkan penggunaan pointer fungsi ke konteks yang didukung (CS8911). Jenis penunjuk fungsi tidak dapat digunakan dalam posisi tertentu, seperti argumen atribut atau ekspresi typeof. Restrukturisasi kode untuk menghindari penggunaan jenis penunjuk fungsi dalam konteks yang tidak didukung.