Mengatasi kesalahan dan peringatan yang terkait dengan parameter jenis generik dan argumen jenis generik

Artikel ini membahas kesalahan pengkompilasi berikut:

  • CS0080: Batasan tidak diizinkan pada deklarasi non-generik.
  • CS0081: Deklarasi parameter jenis harus berupa pengidentifikasi bukan jenis.
  • CS0224: Metode dengan vararg tidak boleh generik, berada dalam jenis generik, atau memiliki parameter param.
  • CS0304: Tidak dapat membuat instans jenis variabel karena tidak memiliki batasan new() .
  • CS0305: Menggunakan jenis generik memerlukan argumen jenis N.
  • CS0306: Jenis tidak dapat digunakan sebagai argumen jenis.
  • CS0307: 'pengidentifikasi' tidak dapat digunakan dengan argumen jenis.
  • CS0308: Jenis atau metode non-generik tidak dapat digunakan dengan argumen jenis.
  • CS0310: Jenis harus merupakan jenis non-abstrak dengan konstruktor tanpa parameter publik untuk menggunakannya sebagai parameter dalam jenis atau metode generik.
  • CS0311: Jenis tidak dapat digunakan sebagai parameter T jenis dalam jenis atau metode generik. Tidak ada konversi referensi implisit dari 'type1' ke 'type2'.
  • CS0312: Jenis 'type1' tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Tipe nullable 'type1' tidak memenuhi batasan 'batasan'.
  • CS0313: Jenis 'type1' tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Tipe nullable 'type1' tidak memenuhi batasan 'batasan'. Jenis nullable tidak dapat memenuhi batasan antarmuka apa pun.
  • CS0314: Tipe ini tidak dapat digunakan sebagai parameter tipe dalam tipe atau metode generik. Tidak ada konversi boxing atau konversi parameter tipe dari 'type' ke 'constraint'.
  • CS0315: Tipe tidak dapat digunakan sebagai parameter tipe T dalam tipe atau metode generik. Tidak ada konversi boxing dari 'type' ke 'constraint'.
  • CS0401: Batasan new() harus menjadi batasan pembatasan terakhir yang ditentukan.
  • CS0403: Tidak dapat mengonversi parameter null ke jenis karena bisa menjadi jenis nilai yang tidak dapat diubah ke null. Pertimbangkan untuk menggunakan default(T) sebagai gantinya.
  • CS0405: Batasan duplikat untuk parameter jenis.
  • CS0406: Batasan jenis kelas 'batasan' harus datang sebelum batasan lainnya.
  • CS0409: Klausa batasan sudah ditentukan untuk parameter tipe 'type parameter'. Semua batasan untuk parameter tipe harus ditentukan dalam satu klausa where.
  • CS0411: Argumen jenis untuk metode 'metode' tidak dapat disimpulkan dari penggunaan. Coba tentukan argumen jenis secara eksplisit.
  • CS0412: Parameter: parameter, variabel lokal, atau fungsi lokal tidak dapat memiliki nama yang sama dengan parameter jenis metode.
  • CS0413: Parameter jenis tidak dapat digunakan dengan as operator karena tidak memiliki batasan jenis kelas atau class batasan.
  • CS0417: Pengidentifikasi: tidak dapat memberikan argumen saat membuat instans jenis variabel.
  • CS0449: Batasan class, , structunmanaged, notnull, dan default tidak dapat digabungkan atau diduplikasi, dan harus ditentukan terlebih dahulu dalam daftar batasan.
  • CS0450: Parameter Jenis: tidak dapat menentukan kelas batasan dan class atau struct batasan.
  • CS0451: Batasan new() tidak dapat digunakan dengan batasan struct .
  • CS0452: Jenis 'nama jenis' harus merupakan jenis referensi untuk menggunakannya sebagai parameter 'nama parameter' dalam jenis generik atau metode 'generik'.
  • CS0453: Jenis 'nama jenis' harus merupakan jenis nilai yang tidak dapat diubah ke null untuk menggunakannya sebagai parameter 'nama parameter' dalam jenis generik atau metode 'generik'.
  • CS0454: Dependensi batasan melingkar yang melibatkan Jenis Parameter 1 dan Jenis Parameter 2.
  • CS0455: Parameter jenis mewarisi batasan yang bertentangan 'batasan1' dan 'batasan2'.
  • CS0456: Parameter jenis 'type parameter 1' memiliki batasan 'struct' sehingga 'type parameter 1' tidak dapat digunakan sebagai batasan untuk 'type parameter 2'.
  • CS0693: Parameter tipe 'type parameter' memiliki nama yang sama dengan parameter tipe dari tipe luar 'type'.
  • CS0694: Parameter jenis memiliki nama yang sama dengan jenis yang berisi, atau metode.
  • CS0695: 'type' tidak dapat mengimplementasikan 'interface1' dan 'interface2' karena dapat menyatukan beberapa jenis substitusi parameter.
  • CS0698: Jenis generik tidak dapat berasal dari jenis karena merupakan kelas atribut.
  • CS0699: 'generic' tidak menentukan parameter jenis 'pengidentifikasi'.
  • CS0701: 'pengidentifikasi' bukan batasan yang valid. Jenis yang digunakan sebagai batasan harus merupakan antarmuka, kelas yang tidak disegel, atau parameter jenis.
  • CS0702: Batasan tidak boleh kelas khusus.
  • CS0703: Aksesibilitas yang tidak konsisten: jenis batasan kurang dapat diakses daripada deklarasi.
  • CS0704: Tidak dapat melakukan pencarian anggota non-virtual dalam 'type' karena merupakan parameter jenis.
  • CS0706: Jenis batasan tidak valid. Jenis yang digunakan sebagai batasan harus merupakan antarmuka, kelas yang tidak disegel, atau parameter jenis.
  • CS0717: Kelas statis: kelas statis tidak dapat digunakan sebagai batasan.
  • CS0718: 'type': tipe statis tidak dapat digunakan sebagai argumen jenis.
  • CS1720: Ekspresi akan selalu menyebabkan System.NullReferenceException karena nilai default dari 'tipe generik' adalah null.
  • CS1763: 'parameter' berjenis 'type'. Nilai parameter default dari jenis referensi selain string hanya dapat diinisialisasi dengan null.
  • CS1948: Variabel rentang 'nama' tidak boleh memiliki nama yang sama dengan parameter jenis metode.
  • CS1960: Pengubah varians tidak valid. Hanya parameter jenis antarmuka dan delegasi yang dapat ditentukan sebagai varian.
  • CS1961: Varians tidak valid: Parameter tipe harus valid secara kovarian pada 'type'. 'parameter tipe' bersifat kontravarian.
  • CS3024: Jenis batasan 'type' tidak sesuai dengan CLS.
  • CS7002: Penggunaan nama generik yang tidak terduga.
  • CS8322: Tidak dapat meneruskan argumen dengan jenis dinamis ke fungsi lokal generik dengan argumen jenis yang disimpulkan.
  • CS8375: Batasan 'new()' tidak dapat digunakan dengan batasan 'tidak terkelola'.
  • CS8377: Tipe 'type' harus berupa tipe nilai non-nullable, beserta semua bidang pada tingkat penyarangan apa pun, agar dapat digunakan sebagai parameter 'parameter' dalam tipe generik atau metode 'generic'.
  • CS8379: Parameter jenis 'type parameter 1' memiliki batasan 'tidak terkelola' sehingga 'type parameter 1' tidak dapat digunakan sebagai batasan untuk 'type parameter 2'.
  • CS8380: 'type': tidak dapat menentukan kelas batasan dan batasan 'tidak terkelola'.
  • CS8387: Parameter tipe 'type parameter' memiliki nama yang sama dengan parameter tipe dari metode terluar 'method'.
  • CS8389: Menghilangkan argumen jenis tidak diizinkan dalam konteks saat ini.
  • CS8427: Enum, kelas, dan struktur tidak dapat dideklarasikan dalam antarmuka yang memiliki parameter jenis 'masuk' atau 'keluar'.
  • CS8665: Metode 'method' menetapkan batasan 'class' untuk parameter tipe 'type parameter', tetapi parameter tipe 'type parameter' yang bersesuaian dari metode 'method' yang ditimpa atau diimplementasikan secara eksplisit bukan tipe referensi.
  • CS8666: Metode 'metode' menentukan batasan 'struct' untuk parameter jenis 'parameter jenis', tetapi parameter jenis 'parameter jenis' yang sesuai dari metode 'metode' yang ditimpa atau diimplementasikan secara eksplisit bukan jenis nilai yang tidak dapat diubah ke null.
  • CS8822: Metode 'method' menetapkan batasan 'default' untuk parameter tipe 'type parameter', tetapi parameter tipe terkait 'type parameter' dari metode 'method' yang dioverride atau diimplementasikan secara eksplisit dibatasi sebagai tipe referensi atau tipe nilai.
  • CS8823: Batasan 'default' valid hanya pada metode penimpaan dan implementasi antarmuka eksplisit.
  • CS8893: 'type' bukan jenis konvensi panggilan yang valid untuk 'UnmanagedCallersOnly'.
  • CS8894: Tidak dapat menggunakan 'type' sebagai parameter atau jenis pengembalian pada metode yang dikaitkan dengan 'UnmanagedCallersOnly'.
  • CS8895: Metode yang diatribusikan dengan 'UnmanagedCallersOnly' tidak dapat memiliki parameter jenis generik dan tidak dapat dideklarasikan dalam jenis generik.
  • CS8896: 'UnmanagedCallersOnly' hanya dapat diterapkan ke metode non-abstrak statis biasa, non-virtual, atau fungsi lokal statis.
  • CS9011: Kata kunci delegate tidak dapat digunakan sebagai batasan. Apa maksudmu System.Delegate?
  • CS9012: Kata kunci recordtak terduga . Apakah maksudmu record struct atau record class?
  • CS9338: Aksesibilitas yang tidak konsisten: jenis kurang dapat diakses daripada kelas.

Deklarasi dan penamaan tipe parameter

  • CS0080: Batasan tidak diizinkan pada deklarasi non-generik.
  • CS0081: Deklarasi parameter jenis harus berupa pengidentifikasi bukan jenis.
  • CS0412: Parameter: parameter, variabel lokal, atau fungsi lokal tidak dapat memiliki nama yang sama dengan parameter jenis metode.
  • CS0693: Parameter tipe 'type parameter' memiliki nama yang sama dengan parameter tipe dari tipe luar 'type'.
  • CS0694: Parameter jenis memiliki nama yang sama dengan jenis yang berisi, atau metode.
  • CS0699: 'generic' tidak menentukan parameter jenis 'pengidentifikasi'.
  • CS1948: Variabel rentang 'nama' tidak boleh memiliki nama yang sama dengan parameter jenis metode.
  • CS8387: Parameter tipe 'type parameter' memiliki nama yang sama dengan parameter tipe dari metode terluar 'method'.
  • CS9012: Kata kunci recordtak terduga . Apakah maksudmu record struct atau record class?

Kesalahan ini berkaitan dengan cara Anda mendeklarasikan dan menamai parameter jenis dalam jenis dan metode generik. Nama parameter jenis harus berupa pengidentifikasi yang valid, tidak boleh bertentangan dengan pengidentifikasi lain dalam cakupan, dan harus muncul dalam daftar parameter jenis deklarasi.

  • Hapus klausa batasan dari deklarasi non-generik (CS0080). Klausa where hanya dapat digunakan pada jenis generik dan metode yang mendeklarasikan parameter jenis. Jika Anda perlu menerapkan batasan, pertama-tama tambahkan parameter jenis ke jenis atau deklarasi metode Anda.
  • Ganti nama jenis aktual dengan pengidentifikasi dalam deklarasi parameter jenis (CS0081). Anda harus mendeklarasikan parameter jenis menggunakan pengidentifikasi (seperti T, TKey, atau TValue) daripada tipe konkret (seperti int atau string). Tujuan dari parameter tipe adalah untuk berfungsi sebagai tempat penampung yang diganti kompiler dengan tipe sebenarnya ketika tipe atau metode generik digunakan.
  • Ganti nama parameter jenis, variabel lokal, parameter, atau variabel rentang untuk menghindari konflik penamaan (CS0412, CS0694, CS1948). Nama parameter tipe tidak boleh membayangi pengidentifikasi dalam cakupan yang sama, dan tidak boleh sama dengan nama tipe atau metode yang memuatnya. Variabel rentang LINQ juga tidak dapat menggunakan kembali nama parameter jenis metode. Konflik tersebut menciptakan ambiguitas tentang pengidentifikasi mana yang sedang dirujuk.
  • Gunakan nama yang berbeda untuk parameter tipe dalam yang menimpa parameter tipe luar (CS0693, CS8387). Ketika anggota generik (seperti metode atau jenis berlapis) berada di dalam kelas atau metode generik, parameter jenis dalam tidak selalu sama dengan yang luar. Memberi mereka nama yang sama membuat kebingungan tentang parameter jenis mana yang sedang direferensikan. Gunakan nama yang berbeda untuk parameter tipe bagian dalam.
  • Pastikan semua parameter jenis dalam klausa batasan dideklarasikan dalam daftar parameter jenis (CS0699). where Klausa hanya dapat mereferensikan parameter jenis yang muncul dalam deklarasi generik. Jika nama dalam where klausul tidak cocok dengan parameter jenis yang dideklarasikan, periksa kesalahan ketik atau kesalahan ejaan.
  • Gunakan sintaks deklarasi rekaman yang benar (CS9012). Saat mendeklarasikan jenis rekaman, Anda harus menggunakan salah satu dari record class atau record struct (atau hanya menggunakan record untuk jenis referensi). Kata record kunci saja tidak dapat muncul di posisi di mana pengkompilasi mengharapkan sintaks deklarasi yang berbeda.

Untuk informasi selengkapnya, lihat Parameter Jenis Generik dan Generik.

Deklarasi dan pengurutan batasan

  • CS0401: Batasan new() harus menjadi batasan pembatasan terakhir yang ditentukan.
  • CS0406: Batasan tipe kelas 'constraint' harus diletakkan sebelum batasan lain.
  • CS0409: Klausa batasan telah ditentukan untuk parameter jenis 'parameter jenis'. Semua batasan untuk parameter jenis harus ditentukan dalam satu klausa where.
  • CS0449: Batasan class, , structunmanaged, notnull, dan default tidak dapat digabungkan atau diduplikasi, dan harus ditentukan terlebih dahulu dalam daftar batasan.
  • CS0450: Parameter Jenis: tidak dapat menentukan kelas batasan dan class atau struct batasan.
  • CS0451: Batasan new() tidak dapat digunakan dengan batasan struct .
  • CS8375: Batasan 'new()' tidak dapat digunakan dengan batasan 'tidak terkelola'.
  • CS8380: 'type': tidak dapat menentukan kelas batasan dan batasan 'tidak terkelola'.
  • CS9011: Kata kunci delegate tidak dapat digunakan sebagai batasan. Apa maksudmu System.Delegate?

Batasan pada parameter jenis harus mengikuti urutan tertentu: batasan utama (class, , struct, unmanagednotnull, atau default) menjadi yang pertama, lalu batasan jenis kelas, diikuti oleh batasan antarmuka, dan akhirnya new() batasan konstruktor. Beberapa batasan saling eksklusif dan tidak dapat digabungkan. Semua batasan untuk parameter jenis tunggal harus muncul dalam satu where klausa.

  • Tempatkan new() batasan di akhir daftar batasan (CS0401). Batasan new() harus muncul setelah semua batasan lainnya. Misalnya, ubah where T : new(), IDisposable menjadi where T : IDisposable, new().
  • Tempatkan batasan jenis kelas sebelum batasan antarmuka (CS0406). Saat Anda membatasi parameter jenis ke kelas dasar tertentu bersama dengan antarmuka, kelas harus muncul terlebih dahulu. Misalnya, ubah where T : IDisposable, MyBaseClass menjadi where T : MyBaseClass, IDisposable.
  • Gabungkan semua batasan untuk parameter jenis ke dalam satu where klausa (CS0409). Anda tidak dapat menggunakan beberapa where klausa untuk parameter jenis yang sama. Gabungkan ke dalam satu klausa: ubah where T : I where T : new() ke where T : I, new(). Beberapa where klausa hanya valid ketika menargetkan parameter jenis yang berbeda.
  • Tempatkan batasan utama terlebih dahulu dan jangan gabungkan batasan yang saling eksklusif (CS0449). Anda dapat menentukan paling banyak salah satu dari class, , struct, unmanagednotnull, atau default, dan harus muncul terlebih dahulu dalam daftar batasan. Batasan class dan struct saling eksklusif, demikian juga class dan unmanaged.
  • Jangan gabungkan batasan kelas tertentu dengan class, , structatau unmanaged (CS0450, CS8380). Jika parameter jenis dibatasi ke jenis kelas tertentu, parameter tersebut secara implisit merupakan jenis referensi, yang bertentangan dengan struct atau unmanaged batasan. Hapus batasan kelas atau batasan utama.
  • Jangan gabungkan new() dengan struct atau unmanaged (CS0451, CS8375). Semua jenis nilai secara implisit memiliki konstruktor tanpa parameter publik, sehingga new() batasannya berlebihan jika dikombinasikan dengan struct. Hal yang sama berlaku untuk unmanaged, yang menyiratkan struct. Hapus batasan new() .
  • Ganti delegate dengan System.Delegate dalam klausa batasan (CS9011). Kata delegate kunci digunakan untuk mendeklarasikan jenis delegasi, bukan sebagai batasan. Untuk membatasi parameter jenis untuk mendelegasikan jenis, gunakan System.Delegate sebagai jenis batasan.

Untuk informasi selengkapnya, lihat Batasan pada Parameter Jenis.

Jenis batasan yang valid

  • CS0405: Batasan duplikat untuk parameter jenis.
  • CS0701: 'pengidentifikasi' bukan batasan yang valid. Jenis yang digunakan sebagai batasan harus merupakan antarmuka, kelas yang tidak disegel, atau parameter jenis.
  • CS0702: Batasan tidak boleh kelas khusus.
  • CS0703: Aksesibilitas yang tidak konsisten: jenis batasan kurang dapat diakses daripada deklarasi.
  • CS0706: Jenis batasan tidak valid. Jenis yang digunakan sebagai batasan harus merupakan antarmuka, kelas yang tidak disegel, atau parameter jenis.
  • CS0717: Kelas statis: kelas statis tidak dapat digunakan sebagai batasan.
  • CS3024: Jenis batasan 'type' tidak sesuai dengan CLS.

Batasan harus berupa antarmuka, kelas yang tidak disegel, atau parameter jenis. Jenis tertentu tidak valid sebagai batasan karena makna khususnya dalam sistem jenis .NET atau karena tidak dapat diwariskan.

  • Hapus batasan duplikat (CS0405). Setiap batasan hanya dapat muncul sekali dalam klausa batasan. Jika Anda memiliki where T : I, I, hapus duplikat.
  • Gunakan hanya jenis yang tidak disegel sebagai batasan (CS0701). Kelas, struktur, dan enum yang disegel tidak dapat diwariskan, sehingga tidak berfungsi sebagai batasan. Gunakan antarmuka yang diterapkan oleh tipe-tipe yang diinginkan, atau gunakan kelas dasar yang tidak disegel.
  • Jangan gunakan kelas khusus sebagai batasan (CS0702). Jenis Object, Array, dan ValueType tidak dapat digunakan sebagai batasan. Setiap jenis sudah berasal dari Object, sehingga membatasinya tidak memberikan nilai. Array dan ValueType merupakan jenis dasar abstrak yang tidak dapat langsung diwariskan. Jika Anda memerlukan perilaku seperti array, gunakan IList<T> atau IEnumerable<T> sebagai gantinya.
  • Pastikan tipe batasan setidaknya sama dapat diaksesnya dengan tipe generik (CS0703). Jenis generik publik tidak dapat memiliki batasan menggunakan jenis internal, karena kode eksternal tidak akan dapat memberikan argumen jenis yang valid. Buat jenis batasan menjadi publik, atau kurangi aksesibilitas jenis generik.
  • Gunakan hanya antarmuka, kelas yang tidak disegel, atau ketik parameter sebagai batasan (CS0706). Anda tidak dapat menggunakan array, kelas tersegel, struktur, enum, atau jenis tidak valid lainnya sebagai batasan. Pertimbangkan untuk menggunakan antarmuka yang diimplementasikan oleh tipe yang diinginkan.
  • Jangan gunakan kelas statis sebagai batasan (CS0717). Kelas statis tidak dapat diperluas karena hanya berisi anggota statis. Tidak ada jenis yang dapat berasal dari kelas statis, membuatnya tidak berguna sebagai batasan.
  • Gunakan jenis yang sesuai dengan CLS untuk batasan jenis (CS3024). Ketika rakitan ditandai dengan [assembly: CLSCompliant(true)], menggunakan jenis yang tidak mematuhi CLS sebagai batasan jenis generik dapat membuatnya tidak mungkin bagi kode yang ditulis dalam beberapa bahasa untuk menggunakan kelas generik Anda.

Untuk informasi selengkapnya, lihat Batasan pada Parameter Jenis.

Pemenuhan batasan dan transformasi

  • CS0311: Jenis tidak dapat digunakan sebagai parameter T jenis dalam jenis atau metode generik. Tidak ada konversi referensi implisit dari 'type1' ke 'type2'.
  • CS0312: Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Tipe nullable tidak memenuhi batasan 'batasan'.
  • CS0313: Jenis tidak dapat digunakan sebagai parameter jenis dalam jenis atau metode generik. Tipe nullable tidak memenuhi batasan 'batasan'. Jenis nullable tidak dapat memenuhi batasan antarmuka apa pun.
  • CS0314: Tipe tidak dapat digunakan sebagai parameter tipe dalam tipe atau metode generik. Tidak ada konversi boxing atau konversi parameter tipe dari 'type' ke 'constraint'.
  • CS0315: Tipe tidak dapat digunakan sebagai parameter tipe T dalam tipe atau metode generik. Tidak ada konversi boxing dari 'type' ke 'constraint'.
  • CS0452: Jenis 'nama jenis' harus merupakan jenis referensi untuk menggunakannya sebagai parameter 'nama parameter' dalam jenis generik atau metode 'generik'.
  • CS0453: Jenis 'nama jenis' harus merupakan jenis nilai yang tidak dapat diubah ke null untuk menggunakannya sebagai parameter 'nama parameter' dalam jenis generik atau metode 'generik'.
  • CS8377: Tipe 'type' harus berupa tipe nilai yang tidak dapat bernilai null, beserta semua bidang di tingkat penyarangan mana pun, agar dapat digunakan sebagai parameter 'parameter' dalam tipe generik atau metode 'generic'.

Kesalahan ini terjadi ketika argumen jenis tidak memenuhi batasan yang dideklarasikan pada parameter jenis generik. Argumen jenis harus memiliki konversi yang benar, hubungan pewarisan, dan properti struktural agar sesuai dengan semua batasan.

  • Ubah argumen jenis menjadi argumen yang memiliki konversi referensi implisit ke jenis batasan (CS0311). Ketika parameter tipe memiliki batasan seperti where T : BaseType, setiap argumen tipe harus dapat dikonversi ke BaseType melalui konversi referensi implisit atau konversi identitas. Konversi numerik implisit (seperti dari short ke int) tidak memenuhi batasan parameter jenis generik.
  • Gunakan jenis nilai yang tidak dapat diubah ke null atau ubah jenis batasan (CS0312, CS0313). Jenis nilai nullable (seperti int?) berbeda dari jenis nilai yang mendasar dan tidak memenuhi batasan yang sama. Jenis nilai nullable tidak dapat memenuhi batasan antarmuka karena pembungkus nullable itu sendiri tidak mengimplementasikan antarmuka. Gunakan bentuk non-nullable dari tipe nilai sebagai argumen tipe.
  • Ulangi batasan parameter jenis kelas dasar dalam deklarasi kelas turunan (CS0314). Ketika kelas generik turunan mewarisi dari kelas generik dasar yang dibatasi, kelas turunan harus menyatakan batasan yang sama pada parameter jenis yang sesuai.
  • Pastikan argumen jenis memenuhi jenis referensi atau batasan kelas (CS0315). Saat parameter tipe dibatasi sebagai tipe kelas, Anda tidak dapat menggunakan tipe nilai (struct) sebagai argumen tipe karena tidak ada konversi boxing yang memenuhi relasi batasan tersebut. Gunakan jenis referensi yang mewarisi dari atau mengimplementasikan batasan.
  • Gunakan jenis referensi sebagai argumen jenis saat class batasan ditentukan (CS0452). Jenis nilai seperti struct atau int tidak dapat memenuhi class batasan. Ubah argumen jenis menjadi jenis referensi, atau hapus class batasan jika jenis generik dapat bekerja dengan jenis nilai.
  • Gunakan jenis nilai yang tidak dapat diubah ke null sebagai argumen jenis saat struct batasan ditentukan (CS0453). Jenis referensi, jenis nilai nullable (int?), dan jenis non-nilai lainnya tidak dapat memenuhi struct batasan. Gunakan tipe nilai konkret yang tidak menerima nilai null, seperti int, double, atau struct yang ditentukan pengguna.
  • Gunakan tipe yang semua field-nya merupakan tipe unmanaged saat batasan unmanaged ditentukan (CS8377). Batasan unmanaged memerlukan jenis nilai yang tidak dapat diubah ke null di mana setiap bidang, di setiap tingkat penumpukan, juga merupakan jenis yang tidak dikelola. Jenis yang berisi bidang bertipe referensi atau parameter tipe generik yang tidak diketahui sebagai tipe tak terkelola tidak memenuhi batasan ini.

Untuk informasi selengkapnya, lihat Batasan pada Parameter Jenis.

Konflik batasan dan dependensi melingkar

  • CS0454: Dependensi batasan melingkar yang melibatkan Parameter Jenis 1 dan Parameter Jenis 2.
  • CS0455: Parameter jenis mewarisi batasan yang bertentangan 'batasan1' dan 'batasan2'.
  • CS0456: Parameter jenis 'type parameter 1' memiliki batasan 'struct' sehingga 'type parameter 1' tidak dapat digunakan sebagai batasan untuk 'type parameter 2'.
  • CS8379: Parameter jenis 'type parameter 1' memiliki batasan 'tidak terkelola' sehingga 'type parameter 1' tidak dapat digunakan sebagai batasan untuk 'type parameter 2'.

Batasan tidak dapat membuat dependensi melingkar, dan parameter jenis tidak dapat mewarisi batasan yang bertentangan yang tidak mungkin untuk dipenuhi secara bersamaan. Batasan jenis nilai (struct dan unmanaged) disegel secara implisit, sehingga tidak dapat digunakan sebagai batasan pada parameter jenis lain.

  • Hapus dependensi batasan melingkar (CS0454). Parameter jenis tidak dapat secara langsung atau tidak langsung bergantung pada dirinya sendiri melalui batasannya. Misalnya, where T : U where U : T membuat dependensi melingkar. Putuskan siklus dengan menghapus salah satu batasan.
  • Hapus batasan yang diwariskan yang bertentangan (CS0455). Parameter jenis tidak dapat dibatasi ke beberapa kelas yang tidak terkait, karena C# tidak mendukung beberapa pewarisan kelas. Demikian pula, ini tidak dapat dibatasi oleh struct dan tipe kelas sekaligus. Restrukturisasi hierarki jenis Anda atau hapus salah satu batasan yang bertentangan.
  • Jangan gunakan structparameter jenis yang dibatasi atau unmanageddibatasi sebagai batasan untuk parameter jenis lain (CS0456, CS8379). Batasan jenis nilai disegel secara implisit, sehingga tidak ada jenis lain yang dapat berasal darinya. Untuk mengatasi kesalahan ini, letakkan jenis nilai atau batasan yang tidak dikelola langsung pada parameter jenis kedua alih-alih membatasinya secara tidak langsung melalui parameter jenis pertama.

Untuk informasi selengkapnya, lihat Batasan pada Parameter Jenis.

Mengesampingkan dan menerapkan aturan batasan

  • CS8665: Metode 'method' menetapkan konstrain 'class' untuk parameter tipe 'type parameter', tetapi parameter tipe 'type parameter' yang bersesuaian dari metode 'method' yang dioverride atau diimplementasikan secara eksplisit bukan tipe referensi.
  • CS8666: Metode 'method' mensyaratkan konstrain 'struct' untuk parameter tipe 'type parameter', tetapi parameter tipe 'type parameter' yang bersesuaian dari metode 'method' yang ditimpa atau diimplementasikan secara eksplisit bukan tipe nilai yang tidak dapat bernilai null.
  • CS8822: Metode 'method' menetapkan batasan 'default' untuk parameter tipe 'type parameter', tetapi parameter tipe terkait 'type parameter' dari metode 'method' yang ditimpa atau diimplementasikan secara eksplisit dibatasi sebagai tipe referensi atau tipe nilai.
  • CS8823: Batasan 'default' valid hanya pada metode penimpaan dan implementasi antarmuka eksplisit.

Saat Anda mengganti metode virtual atau secara eksplisit mengimplementasikan metode antarmuka, batasan pada parameter tipe metode yang mengganti harus kompatibel dengan batasan metode dasar. Kendala default adalah pengubah khusus yang hanya digunakan dalam skenario override dan implementasi antarmuka eksplisit untuk menunjukkan bahwa parameter tipe tidak memiliki batasan class maupun struct.

  • Pastikan batasan metode penimpaan cocok dengan batasan metode dasar (CS8665, CS8666). Override tidak dapat menambahkan batasan class jika parameter tipe terkait pada metode induk tidak dibatasi sebagai tipe referensi. Demikian pula, itu tidak dapat menambahkan struct batasan jika parameter jenis metode dasar tidak dibatasi ke jenis nilai. Override harus kompatibel dengan deklarasi basis.
  • default Gunakan batasan hanya ketika parameter jenis metode dasar tidak dibatasi (CS8822). Konstrain default menunjukkan bahwa parameter tipe tidak memiliki konstrain class atau struct. Anda tidak dapat menerapkan default jika parameter tipe yang sesuai dari metode yang dioverride sudah memiliki konstrain class atau struct.
  • Gunakan default batasan hanya pada metode override atau metode implementasi antarmuka eksplisit (CS8823). Batasan default tidak valid pada deklarasi metode reguler. Ini secara khusus digunakan untuk menghilangkan ambiguitas saat meng-override metode ketika kelas dasar memiliki parameter tipe yang tidak dibatasi, dan Anda perlu menunjukkan bahwa override tersebut juga membiarkannya tetap tidak dibatasi.

Untuk informasi selengkapnya, lihat Batasan pada parameter jenis dan batasannyadefault.

Pembatasan konstruktor

  • CS0304: Tidak dapat membuat instans jenis variabel karena tidak memiliki batasan new() .
  • CS0310: Jenis harus merupakan jenis non-abstrak dengan konstruktor tanpa parameter publik untuk menggunakannya sebagai parameter dalam jenis atau metode generik.
  • CS0417: Pengidentifikasi: tidak dapat memberikan argumen saat membuat instans jenis variabel.

Kesalahan ini terkait dengan batasan new() dan instansiasi parameter tipe menggunakan operator new.

  • Tambahkan batasan new() ke parameter tipe yang perlu Anda instansiasi (CS0304). Saat Anda menggunakan new T() di dalam jenis atau metode generik, pengkompilasi harus menjamin bahwa argumen jenis apa pun memiliki konstruktor tanpa parameter. Batasan new() memberikan jaminan ini.
  • Pastikan argumen jenis memiliki konstruktor tanpa parameter publik (CS0310). Ketika parameter jenis memiliki new() batasan, jenis beton apa pun yang digunakan sebagai argumen jenis harus non-abstrak dan harus menyediakan konstruktor tanpa parameter publik. Tipe yang hanya memiliki konstruktor privat, terproteksi, atau berparameter tidak dapat memenuhi batasan new().
  • Hapus argumen konstruktor saat menginstansiasi parameter jenis (CS0417). Batasan new() hanya menjamin konstruktor tanpa parameter. Anda tidak dapat meneruskan argumen ke new T(arguments). Jika Anda perlu membuat instans dengan argumen tertentu, pertimbangkan untuk menggunakan pola pabrik atau batasan antarmuka yang menentukan perilaku konstruksi.

Untuk informasi selengkapnya, lihat Batasan pada parameter jenis dan batasannyanew().

Ketik jumlah argumen dan penggunaan

  • CS0224: Metode dengan vararg tidak boleh generik, berada dalam jenis generik, atau memiliki parameter param.
  • CS0305: Menggunakan jenis generik memerlukan argumen jenis N.
  • CS0306: Jenis tidak dapat digunakan sebagai tipe argumen.
  • CS0307: 'pengidentifikasi' tidak dapat digunakan dengan argumen jenis.
  • CS0308: Jenis atau metode non-generik tidak dapat digunakan dengan argumen jenis.
  • CS7002: Penggunaan nama generik yang tidak terduga.
  • CS8389: Menghilangkan argumen jenis tidak diizinkan dalam konteks saat ini.

Kesalahan ini berkaitan dengan memberikan jumlah dan jenis argumen yang benar ke jenis dan metode generik.

  • Hapus parameter jenis generik atau berisi deklarasi jenis generik dari metode yang menggunakan __arglist (CS0224). Kata __arglist kunci tidak kompatibel dengan generik karena mekanisme runtime untuk menangani daftar argumen variabel bertentangan dengan substitusi jenis yang diperlukan untuk parameter jenis generik.
  • Berikan jumlah pasti argumen jenis yang ditentukan dalam deklarasi generik (CS0305). Setiap parameter jenis generik dalam definisi harus memiliki argumen jenis yang sesuai ketika jenis generik dibuat.
  • Gunakan hanya tipe yang valid sebagai argumen jenis (CS0306). Jenis penunjuk (seperti int* atau char*) tidak dapat digunakan sebagai argumen jenis karena jenis generik memerlukan jenis terkelola yang dapat dilacak pengumpul sampah.
  • Hapus sintaks argumen jenis dari konstruksi non-generik (CS0307, CS0308). Argumen jenis yang diapit dalam tanda kurung sudut hanya dapat diterapkan ke jenis generik dan metode yang mendeklarasikan parameter jenis. Pastikan Anda mengimpor namespace yang berisi versi generik dari tipe tersebut.
  • Hapus parameter jenis dari deklarasi yang tidak mendukung generik (CS7002). Beberapa konstruksi, seperti enum, tidak bisa generik. Jika Anda memerlukan kontainer generik untuk nilai enum, pertimbangkan untuk menggunakan kelas generik atau struktur sebagai gantinya.
  • Berikan semua argumen jenis yang diperlukan secara eksplisit (CS8389). Dalam beberapa konteks, seperti menggunakan typeof operator atau membuat delegasi, Anda harus menyediakan semua argumen jenis dan tidak dapat menghilangkannya. Misalnya, gunakan typeof(List<int>) daripada mencoba menghilangkan argumen jenis.

Untuk informasi selengkapnya, lihat Parameter Jenis Generik dan Generik.

Inferensi argumen tipe

  • CS0411: Argumen jenis untuk metode 'metode' tidak dapat disimpulkan dari penggunaan. Coba tentukan argumen jenis secara eksplisit.

Kesalahan ini terjadi ketika Anda memanggil metode generik tanpa secara eksplisit menyediakan argumen jenis dan pengkompilasi tidak dapat menyimpulkan argumen jenis mana yang Anda inginkan. Kompilator menyimpulkan argumen tipe dari tipe argumen metode yang Anda berikan pada lokasi pemanggilan.

  • Tentukan argumen jenis secara eksplisit dalam tanda kurung sudut (CS0411). Jika pengkompilasi tidak dapat menentukan argumen jenis dari argumen metode, berikan secara langsung. Misalnya, ubah G() menjadi G<int>(). Kesalahan ini biasanya terjadi ketika metode generik tidak memiliki parameter untuk menyimpulkan jenis, atau ketika null argumen diteruskan dan pengkompilasi tidak dapat menentukan jenis yang dimaksudkan.

Untuk informasi selengkapnya, lihat Metode Generik.

Variasi tipe parameter

  • CS1960: Pengubah varians tidak valid. Hanya parameter jenis antarmuka dan delegasi yang dapat ditentukan sebagai varian.
  • CS1961: Varians tidak valid: Parameter tipe harus valid secara kovarian pada 'type'. 'type parameter' bersifat kontravarian.
  • CS8427: Enum, kelas, dan struktur tidak dapat dideklarasikan dalam antarmuka yang memiliki parameter jenis 'masuk' atau 'keluar'.

Pengubah varians (in untuk kontravariansi, out untuk kovarians) mengontrol bagaimana Anda dapat menggunakan parameter jenis dalam antarmuka dan mendelegasikan deklarasi. Hanya antarmuka dan delegasi yang mendukung varians. Parameter jenis kovarian (out) hanya dapat muncul dalam posisi output (jenis pengembalian), sementara parameter jenis kontravarian (in) hanya dapat muncul dalam posisi input (jenis parameter).

  • Gunakan pengubah varians hanya pada parameter tipe antarmuka dan delegat (CS1960). Kelas, struktur, dan deklarasi jenis lainnya tidak mendukung pengubah varians. Hanya interface dan delegate deklarasi dapat menggunakan in atau out pada parameter jenisnya.
  • Gunakan out (kovarian) untuk parameter jenis yang hanya muncul dalam jenis pengembalian, dan in (kontravarian) untuk parameter jenis yang hanya muncul dalam jenis parameter (CS1961). Jika parameter jenis harus muncul di posisi input dan output, hapus pengubah varians.
  • Jangan mendeklarasikan enum, kelas, atau struktur di dalam antarmuka varian (CS8427). Deklarasi tipe bertingkat di dalam antarmuka yang memiliki parameter tipe in atau out tidak diizinkan karena dapat melanggar aturan keamanan varians. Pindahkan tipe tersarang ke luar deklarasi antarmuka.

Untuk informasi selengkapnya, lihat Kovariansi dan Kontravariansi di Generik.

Pembatasan penggunaan tipe generik

  • CS0403: Tidak dapat mengonversi parameter null ke jenis karena bisa menjadi jenis nilai yang tidak dapat diubah ke null. Pertimbangkan untuk menggunakan default(T) sebagai gantinya.
  • CS0413: Parameter jenis tidak dapat digunakan dengan as operator karena tidak memiliki batasan jenis kelas atau class batasan.
  • CS0695: 'type' tidak dapat mengimplementasikan 'interface1' dan 'interface2' karena dapat menyatukan beberapa jenis substitusi parameter.
  • CS0698: Jenis generik tidak dapat berasal dari jenis karena merupakan kelas atribut.
  • CS0704: Tidak dapat melakukan pencarian anggota non-virtual pada 'type' karena 'type' merupakan parameter tipe.
  • CS0718: 'type': tipe statis tidak dapat digunakan sebagai argumen jenis.
  • CS1720: Ekspresi akan selalu menyebabkan System.NullReferenceException karena nilai default 'tipe generik' adalah null.
  • CS1763: 'parameter' berjenis 'type'. Nilai parameter default dari jenis referensi selain string hanya dapat diinisialisasi dengan null.
  • CS8322: Tidak dapat meneruskan argumen dengan jenis dinamis ke fungsi lokal generik dengan argumen jenis yang disimpulkan.
  • CS9338: Aksesibilitas yang tidak konsisten: jenis kurang dapat diakses daripada kelas.

Kesalahan ini terkait dengan pembatasan tentang bagaimana jenis generik dan parameter jenis dapat digunakan dalam ekspresi, pewarisan, dan akses anggota.

  • Ganti null tugas dengan default(T) atau tambahkan class batasan (CS0403). Saat Anda menetapkan null ke parameter jenis yang tidak dibatasi, pengkompilasi tidak dapat menjamin argumen jenis adalah jenis referensi. Gunakan default(T), yang menyediakan nilai default yang sesuai untuk jenis apa pun, atau tambahkan class batasan jika Anda secara khusus memerlukan semantik jenis referensi.
  • Tambahkan batasan jenis yang spesifik atau ketika menggunakan operator class (as). Operator as mengembalikan null jika konversi gagal, tetapi jenis nilai tidak boleh null. class Tambahkan batasan untuk memastikan parameter jenis selalu merupakan jenis referensi.
  • Hindari menerapkan antarmuka generik yang sama beberapa kali dengan parameter jenis yang dapat menyatukan (CS0695). Ketika kelas menerapkan antarmuka generik beberapa kali dengan parameter jenis yang berbeda (seperti class G<T1, T2> : I<T1>, I<T2>), membuat instans dengan jenis yang sama untuk kedua parameter akan membuat konflik. Terapkan antarmuka hanya sekali, atau restrukturisasi untuk mencegah penyatuan.
  • Hapus parameter jenis generik dari kelas atribut (CS0698). Kesalahan ini tidak lagi diproduksi dalam versi C#saat ini, karena atribut generik sekarang didukung.
  • Gunakan tipe batasan spesifik alih-alih parameter tipe untuk akses anggota bertingkat (CS0704). Anda tidak dapat mengakses jenis berlapis atau anggota non-virtual melalui parameter jenis. Alih-alih T.InnerType, gunakan jenis batasan yang diketahui secara langsung, seperti BaseClass.InnerType.
  • Jangan gunakan tipe statis sebagai argumen tipe (CS0718). Jenis statis tidak dapat dibuat instans dan tidak dapat digunakan sebagai argumen generik. Hapus jenis statis dari argumen generik.
  • Hindari memanggil anggota instans pada default(T) saat T dibatasi ke tipe referensi (CS1720). Ketika T memiliki batasan class, default(T) adalah null, sehingga mengakses anggota instans padanya selalu melempar NullReferenceException. Tambahkan pemeriksaan null sebelum memanggil anggota, atau restrukturisasi kode untuk menghindari penggunaan default(T) secara langsung.
  • Gunakan null sebagai nilai parameter default untuk parameter opsional yang jenisnya adalah jenis referensi (CS1763). Jika metode generik memiliki parameter jenis T dan T merupakan jenis referensi, ganti default(U) dengan null karena default parameter opsional harus konstanta waktu kompilasi, dan default(T) tidak memperbaiki persyaratan tersebut.
  • Tentukan argumen jenis secara eksplisit saat meneruskan nilai dinamis ke fungsi lokal generik (CS8322). Saat Anda meneruskan dynamic argumen ke fungsi lokal generik, pengkompilasi tidak dapat menyimpulkan argumen jenis. Tentukan argumen jenis secara eksplisit atau transmisikan nilai dinamis.
  • Pastikan argumen tipe yang digunakan dalam signature publik atau protected setidaknya sama aksesibelnya dengan anggotanya (CS9338). Anggota generik publik harus menggunakan argumen jenis yang dapat diakses publik. Buat argumen jenis menjadi publik, atau kurangi aksesibilitas anggota.

Untuk informasi selengkapnya, lihat Batasan pada parameter jenis dan ekspresi nilai default.

UnmanagedCallersOnly pembatasan

  • CS8893: 'type' bukan jenis konvensi panggilan yang valid untuk 'UnmanagedCallersOnly'.
  • CS8894: Tidak dapat menggunakan 'type' sebagai parameter atau jenis pengembalian pada metode yang dikaitkan dengan 'UnmanagedCallersOnly'.
  • CS8895: Metode yang diatribusikan dengan 'UnmanagedCallersOnly' tidak dapat memiliki parameter jenis generik dan tidak dapat dideklarasikan dalam jenis generik.
  • CS8896: 'UnmanagedCallersOnly' hanya dapat diterapkan ke metode non-abstrak statis biasa, non-virtual, atau fungsi lokal statis.

Atribut UnmanagedCallersOnlyAttribute menandai metode yang dapat dipanggil kode yang tidak dikelola. Metode ini memiliki persyaratan yang ketat karena runtime harus menangani transisi antara konvensi panggilan terkelola dan tidak terkelola.

  • Gunakan hanya jenis konvensi panggilan yang valid dalam UnmanagedCallersOnly atribut (CS8893). Properti CallConvs dari atribut hanya menerima jenis konvensi pemanggilan yang dikenali dari namespace System.Runtime.CompilerServices.
  • Gunakan hanya jenis yang dapat di-blittable sebagai parameter dan jenis pengembalian (CS8894). Metode yang ditandai dengan UnmanagedCallersOnly tidak dapat menggunakan jenis terkelola (seperti string atau object) sebagai parameter atau jenis pengembalian karena penelepon yang tidak dikelola tidak dapat mengelola referensi yang dikumpulkan sampah.
  • Hapus parameter jenis generik dari UnmanagedCallersOnly metode dan jangan mendeklarasikannya dalam jenis generik (CS8895). Konvensi panggilan yang tidak dikelola tidak mendukung generik karena runtime tidak dapat menentukan konvensi panggilan yang benar untuk substitusi jenis generik.
  • Terapkan UnmanagedCallersOnly hanya pada metode biasa yang statis, nonabstrak, dan nonvirtual, atau fungsi lokal statis (CS8896). Metode instans, metode abstrak, dan metode virtual tidak dapat ditandai dengan UnmanagedCallersOnly karena penelepon yang tidak dikelola tidak dapat melakukan mekanisme pengiriman yang diperlukan metode ini.

Untuk informasi selengkapnya, lihat UnmanagedCallersOnlyAttribute .