C # generic "де обмеження" з визначенням "будь-якого загального типу"?


113

Наведу приклад:

  1. У мене є загальне визначення класу / інтерфейсу:

    interface IGenericCar< T > {...}

  2. У мене є ще один клас / інтерфейс, який я хочу пов'язати з класом вище, наприклад:

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

В принципі, я хочу , щоб мій загальний IGarrage залежати від IGenericCar, незалежно від того , це IGenericCar<int>або IGenericCar<System.Color>, тому що у мене немає якоїсь - якої залежності до цього типу.

Відповіді:


142

Зазвичай це два способи досягти цього.

Варіант1 : Додайте інший параметр до IGarrageпредставлення того, Tщо має бути передано у IGenericCar<T>обмеження:

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

Варіант2 : Визначте базовий інтерфейс, IGenericCar<T>який не є загальним та обмежує цей інтерфейс

interface IGenericCar { ... }
interface IGenericCar<T> : IGenericCar { ... }
interface IGarrage<TCar> where TCar : IGenericCar { ... }

6
Гаразд, але що мені робити, якщо мені потрібно використовувати загальний тип Tвсередині IGarage<TCar>? Я не бачу жодної можливості у варіанті2. Найкращим рішенням було б, якби його було IGarage<TCar>знайдено Tшляхом аналізу типу TCar.
pt12lol

2
Для нащадків може бути створений тип CAN, який має параметр типу необробленого загального типу, але тільки з відображенням під час виконання, і створений клас ніколи не може бути побудований, тому що параметр необробленого типу типу ніколи не може бути побудований автоматично без повного визначення відповідного параметра типу ITS. Я не бачу, де це може бути корисним, за винятком випадків, коли надгенеричні статичні члени найвіддаленішого класу (тобто IGarage<IGenericCar<?>>.TellMeAboutCarsInGeneral(), що, мабуть, буде наслідком поганої конструкції), але я це зробив у своєму майстерності, і це можливо.
Майкл Гофман

Я припускаю, що хтось може додати інтерфейс IGenericCar до класу та розбити обмежений метод з несподіваним класом.
N-ate

2
@ pt12lol: Якщо IGarrage<TCar>насправді обробляє базовий загальний тип (наприклад, він обробляє властивість вказаного типу), тоді він повинен знати тип, який вимагає вказати тип, який є варіантом 1 (єдиний придатний варіант тоді). Однак якщо IGarrage<TCar>безпосередньо не обробляється базовий загальний тип (весь IGarrage<TCar>код є агностиком цього базового типу), тоді варіант 2 є дійсним.
Flater

6

Чи має сенс робити щось на кшталт:

interface IGenericCar< T > {...}
interface IGarrage< TCar, TCarType > 
    where TCar: IGenericCar< TCarType > {...}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.