C # generic "where constraint" dengan definisi "any generic type"?

113

Izinkan saya memberi contoh:

  1. Saya memiliki beberapa definisi kelas / antarmuka generik:

    interface IGenericCar< T > {...}

  2. Saya memiliki kelas / antarmuka lain yang ingin saya kaitkan dengan kelas di atas, misalnya:

    interface IGarrage< TCar > : where TCar: IGenericCar< (**any type here**) > {...}

Pada dasarnya, saya ingin IGarrage generik saya bergantung IGenericCar, terlepas dari apakah itu IGenericCar<int>atau IGenericCar<System.Color>, karena saya tidak memiliki ketergantungan pada tipe itu.

Nenad
sumber

Jawaban:

142

Biasanya ada 2 cara untuk mencapai ini.

Option1 : Tambahkan parameter lain untuk IGarragemewakili Tyang harus diteruskan ke dalam IGenericCar<T>batasan:

interface IGarrage<TCar,TOther> where TCar : IGenericCar<TOther> { ... }

Opsi2 : Tentukan antarmuka dasar IGenericCar<T>yang tidak umum dan membatasi antarmuka itu

interface IGenericCar { ... }
interface IGenericCar<T> : IGenericCar { ... }
interface IGarrage<TCar> where TCar : IGenericCar { ... }
JaredPar
sumber
6
Oke, tapi apa yang harus saya lakukan jika saya perlu menggunakan tipe generik saya Tdi dalam IGarage<TCar>? Saya tidak bisa melihat kemungkinan di option2. Solusi terbaik adalah jika IGarage<TCar>menemukan tipe Tdengan menganalisis tipe TCar.
pt12lol
2
Untuk posterity, tipe CAN dibuat yang memiliki parameter tipe dari tipe generik mentah, tetapi hanya dengan refleksi saat runtime, dan kelas yang dibuat tidak akan pernah bisa dibuat, karena parameter tipe generik mentah tidak akan pernah bisa dibangun secara otomatis tanpa definisi lengkap parameter tipe masing-masing ITS. Saya tidak melihat di mana ini bisa berguna, kecuali dalam kasus di mana anggota statis super-generik dari kelas terluar (yaitu IGarage<IGenericCar<?>>.TellMeAboutCarsInGeneral(), yang mungkin akan menjadi hasil dari desain yang buruk), tetapi saya telah melakukannya dalam mengutak-atik saya, dan itu adalah mungkin.
Michael Hoffmann
Saya berasumsi setiap orang dapat menambahkan antarmuka IGenericCar ke kelas dan memecahkan metode yang dibatasi dengan kelas yang tidak terduga.
N-makan
2
@ pt12lol: Jika IGarrage<TCar>benar-benar menangani tipe generik yang mendasarinya (misalnya menangani properti dari tipe tersebut), maka ia perlu mengetahui tipenya, yang mengharuskan Anda menentukan tipe, yaitu opsi 1 (saat itu satu-satunya opsi yang layak). Namun, jika IGarrage<TCar>tidak secara langsung menangani tipe generik yang mendasari (semua IGarrage<TCar>kode agnostik dari tipe yang mendasari ini), maka opsi 2 valid.
Flater
6

Apakah masuk akal untuk melakukan sesuatu seperti:

interface IGenericCar< T > {...}
interface IGarrage< TCar, TCarType > 
    where TCar: IGenericCar< TCarType > {...}
snarf
sumber