C # generische "where-Einschränkung" mit "beliebiger generischer Typ" -Definition?

112

Lassen Sie mich ein Beispiel geben:

  1. Ich habe eine generische Klassen- / Schnittstellendefinition:

    interface IGenericCar< T > {...}

  2. Ich habe eine andere Klasse / Schnittstelle, die ich mit der obigen Klasse in Beziehung setzen möchte, zum Beispiel:

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

Grundsätzlich möchte ich, dass meine generische IGarrage abhängig ist IGenericCar, unabhängig davon, ob es IGenericCar<int>oder ist IGenericCar<System.Color>, da ich keine Abhängigkeit von diesem Typ habe.

Nenad
quelle

Antworten:

141

Es gibt normalerweise zwei Möglichkeiten, um dies zu erreichen.

Option 1 : Fügen Sie einen weiteren Parameter zur IGarrageDarstellung des Parameters hinzu, der Tan die IGenericCar<T>Einschränkung übergeben werden soll:

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

Option 2 : Definieren Sie eine Basisschnittstelle, IGenericCar<T>die nicht generisch ist, und beschränken Sie sich auf diese Schnittstelle

interface IGenericCar { ... }
interface IGenericCar<T> : IGenericCar { ... }
interface IGarrage<TCar> where TCar : IGenericCar { ... }
JaredPar
quelle
6
Ok, aber was soll ich tun, wenn ich meinen generischen Typ Tin der verwenden muss IGarage<TCar>? Ich kann in Option2 keine Möglichkeit sehen. Die beste Lösung wäre, wenn IGarage<TCar>der Typ Tdurch Analysieren des Typs gefunden würde TCar.
Pt12lol
2
Für die Nachwelt kann ein Typ erstellt werden, der einen Typparameter eines generischen Rohtyps enthält, jedoch nur mit Reflexion zur Laufzeit, und die erstellte Klasse könnte niemals konstruiert werden, da der rohe generische Typparameter niemals ohne eine vollständige Definition automatisch konstruiert werden könnte des jeweiligen ITS-Typparameters. Ich sehe nicht, wo dies nützlich sein könnte, außer in Fällen, in denen übergenerische statische Mitglieder der äußersten Klasse (dh IGarage<IGenericCar<?>>.TellMeAboutCarsInGeneral()was wahrscheinlich das Ergebnis eines schlechten Designs wäre), aber ich habe es in meinem Basteln getan, und es ist möglich.
Michael Hoffmann
Ich gehe davon aus, dass jeder einer Klasse die IGenericCar-Schnittstelle hinzufügen und die eingeschränkte Methode mit einer unerwarteten Klasse aufheben kann.
N-aß
2
@ pt12lol: Wenn IGarrage<TCar>der zugrunde liegende generische Typ tatsächlich behandelt wird (z. B. eine Eigenschaft dieses Typs), muss er den Typ kennen, für den Sie den Typ angeben müssen, bei dem es sich um Option 1 handelt (die einzige realisierbare Option). Wenn IGarrage<TCar>der zugrunde liegende generische Typ jedoch nicht direkt behandelt wird (der gesamte IGarrage<TCar>Code ist unabhängig von diesem zugrunde liegenden Typ), ist Option 2 gültig.
Flater
6

Wäre es sinnvoll, etwas zu tun wie:

interface IGenericCar< T > {...}
interface IGarrage< TCar, TCarType > 
    where TCar: IGenericCar< TCarType > {...}
Snarf
quelle