Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet article traite des erreurs suivantes du compilateur :
- CS0080 : Les contraintes ne sont pas autorisées sur les déclarations non génériques.
- CS0081 : La déclaration de paramètre de type doit être un identificateur, et non un type.
- CS0224 : Une méthode avec vararg ne peut pas être générique, être dans un type générique ou avoir un paramètre params.
-
CS0304 : Impossible de créer une instance du type de variable, car elle n’a pas la
new()contrainte. - CS0305 : L’utilisation du type générique nécessite des arguments de type N.
- CS0306 : Le type peut ne pas être utilisé comme argument de type.
- CS0307 : L’identificateur n’est pas une méthode générique. Si vous avez prévu une liste d’expressions, utilisez des parenthèses autour de l’expression.
- CS0308 : Impossible d’utiliser la méthode ou le type non générique avec des arguments de type.
- CS0310 : Le type doit être un type non abstrait avec un constructeur sans paramètre public afin de l’utiliser comme paramètre dans le type générique ou la méthode.
-
CS0311 : Le type ne peut pas être utilisé comme paramètre
Tde type dans le type générique ou la méthode. Il n’existe aucune conversion de référence implicite de type1 en type2. - CS0312 : Le type 'type1' ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Le type nullable 'type1' ne répond pas à la contrainte.
- CS0313 : Le type 'type1' ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Le type nullable 'type1' ne répond pas à la contrainte. Les types nullables ne peuvent pas satisfaire à des contraintes d’interface.
- CS0314 : Le type ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Il n’existe aucune conversion par boxing ou conversion de type de paramètre.
-
CS0315 : Le type ne peut pas être utilisé comme paramètre
Tde type dans le type générique ou la méthode. Il n’y a pas de conversion de boxe. -
CS0401 : La
new()contrainte doit être la dernière contrainte spécifiée. -
CS0403 : Impossible de convertir null en paramètre de type, car il peut s’agir d’un type valeur non nullable. Envisagez plutôt d’utiliser
default(T). - CS0405 : Contrainte dupliquée pour le paramètre de type.
- CS0412: Paramètre : un paramètre, une variable locale ou une fonction locale ne peut pas avoir le même nom qu’un paramètre de type de méthode.
-
CS0413 : Le paramètre de type ne peut pas être utilisé avec l’opérateur
as, car il n’a pas de contrainte de type de classe ni declasscontrainte. - CS0417 : Identificateur : ne peut pas fournir d’arguments lors de la création d’une instance d’un type de variable.
-
CS0449 : Les contraintes
class,struct,unmanaged,notnulletdefaultne peuvent pas être combinées ou dupliquées, et doivent être spécifiées en premier dans la liste des contraintes. -
CS0450 : Paramètre de type : ne peut pas spécifier à la fois une classe de contrainte et la contrainte
classoustruct. -
CS0451 : La
new()contrainte ne peut pas être utilisée avec lastructcontrainte. - CS0454 : dépendance de contrainte circulaire impliquant le paramètre de type 1 et le paramètre de type 2.
- CS0455 : Le paramètre de type hérite des contraintes conflictuelles.
- CS0694 : Le paramètre de type a le même nom que le type ou la méthode conteneur.
-
CS0695 :
Timpossible d’implémenter les deux interfaces, car elles peuvent unifier pour certaines substitutions de paramètres de type. - CS0698 : un type générique ne peut pas dériver du type, car il s’agit d’une classe d’attributs.
- CS0702 : La contrainte ne peut pas être une classe spéciale.
- CS0703 : Accessibilité incohérente : le type de contrainte est moins accessible que la déclaration.
- CS0706 : Type de contrainte non valide. Un type utilisé comme contrainte doit être une interface, une classe non scellée ou un paramètre de type.
- CS0717 : Classe statique : les classes statiques ne peuvent pas être utilisées comme contraintes.
- CS1961 : Variance non valide : le paramètre de type doit être validement variant sur le type.
- CS7002 : Utilisation inattendue d’un nom générique.
- CS8322 : Impossible de passer un argument avec un type dynamique à une fonction locale générique avec des arguments de type déduits.
-
CS9011 : Le mot clé
delegatene peut pas être utilisé comme contrainte. Tu veux direSystem.Delegate? -
CS9012 : mot clé
recordinattendu . Tu veux direrecord structourecord class? - CS9338 : Accessibilité incohérente : le type est moins accessible que la classe.
Déclaration de paramètre de type et nommage
Les erreurs suivantes concernent la façon dont vous déclarez et nommez des paramètres de type dans les types et méthodes génériques :
- CS0080 : Les contraintes ne sont pas autorisées sur les déclarations non génériques.
- CS0081 : La déclaration de paramètre de type doit être un identificateur, et non un type.
- CS0412: Paramètre : un paramètre, une variable locale ou une fonction locale ne peut pas avoir le même nom qu’un paramètre de type de méthode.
- CS0694 : Le paramètre de type a le même nom que le type ou la méthode conteneur.
-
CS9012 : mot clé
recordinattendu . Tu veux direrecord structourecord class?
Pour corriger ces erreurs, vérifiez que vous déclarez des paramètres de type avec des identificateurs valides, appliquez des clauses de contrainte uniquement aux déclarations génériques et évitez les conflits de nommage avec d’autres identificateurs dans l’étendue :
- Supprimez la clause de contrainte des déclarations non génériques (CS0080). La
whereclause ne peut être utilisée que sur les types génériques et les méthodes qui déclarent des paramètres de type, car les contraintes définissent les exigences que les arguments de type doivent satisfaire. Si vous devez appliquer des contraintes, commencez par ajouter des paramètres de type à votre déclaration de type ou de méthode. Par exemple, remplacezpublic class MyClass where MyClass : System.IDisposableparpublic class MyClass<T> where T : System.IDisposable. - Remplacez les noms de types réels par des identificateurs dans les déclarations de paramètres de type (CS0081). Vous devez déclarer des paramètres de type à l’aide d’identificateurs (comme
T, ouTKeyTValue) plutôt que de types concrets (commeintoustring). L’objectif d’un paramètre de type est de servir d’espace réservé que le compilateur remplace par des types réels lorsque le type générique ou la méthode est utilisé. Par exemple, remplacezpublic void F<int>()parpublic void F<T>(). - Renommez les paramètres de type, les variables locales ou les paramètres pour éviter les conflits de nommage (CS0412, CS0694). Les noms de paramètres de type ne peuvent pas masquer les identificateurs dans la même étendue. Ils ne peuvent pas correspondre au nom du type ou de la méthode contenant. Ces conflits créent une ambiguïté sur l'identificateur qui est référencé. Par exemple, si vous avez une méthode
public void F<T>(), vous ne pouvez pas déclarer une variabledouble Tlocale à l’intérieur de cette méthode et vous ne pouvez pas nommer un paramètre de type identique à son type conteneur (class C<C>). - Utilisez la syntaxe de déclaration d’enregistrement correcte (CS9012). Lors de la déclaration d’un type d’enregistrement, vous devez utiliser
record classrecord structou (ou simplementrecordpour un type référence). Lerecordmot clé seul ne peut pas apparaître dans des positions où le compilateur attend une syntaxe de déclaration de type. Par exemple, si vous vouliez déclarer un type d’enregistrement, écrivezrecord class MyRecordourecord struct MyRecord, plutôt que d’utiliserrecordoù un mot clé différent est attendu.
Pour plus d’informations, consultez Paramètres de type générique et génériques.
Déclaration et ordonnancement des contraintes
Les erreurs suivantes concernent la syntaxe et l’ordre des contraintes sur les paramètres de type générique :
-
CS0401 : La
new()contrainte doit être la dernière contrainte spécifiée. -
CS0449 : Les contraintes
class,struct,unmanaged,notnulletdefaultne peuvent pas être combinées ou dupliquées, et doivent être spécifiées en premier dans la liste des contraintes. - CS0450 : Paramètre de type : ne peut pas spécifier à la fois une classe de contrainte et la contrainte
classoustruct. -
CS0451 : La
new()contrainte ne peut pas être utilisée avec lastructcontrainte. -
CS9011 : Le mot clé
delegatene peut pas être utilisé comme contrainte. Tu veux direSystem.Delegate?
Les contraintes sur les paramètres de type doivent suivre un ordre spécifique : les contraintes primaires (class, struct, , unmanagednotnullou default) viennent en premier, suivies des contraintes d’interface ou de classe, et enfin la contrainte du new() constructeur. Certaines contraintes s’excluent mutuellement et ne peuvent pas être combinées.
Pour corriger ces erreurs :
- Placez la
new()contrainte à la fin de la liste de contraintes (CS0401). Lanew()contrainte doit apparaître après toutes les autres contraintes. Par exemple, remplacezwhere T : new(), IDisposableparwhere T : IDisposable, new(). - Placez d’abord les contraintes primaires et ne combinez pas les contraintes mutuellement exclusives (CS0449). Vous pouvez spécifier au maximum l'un des
class,struct,unmanaged,notnulloudefault, et il doit apparaître en premier dans la liste de contraintes. Les contraintesclassetstructsont mutuellement exclusives, tout commeclassetunmanaged. Dans un contexte nullable,classimpliquenotnulldéjà , de sorte qu’ils ne peuvent pas être combinés. - Ne combinez pas de contrainte de classe spécifique avec
struct(CS0450). Si un paramètre de type est limité à un type de classe spécifique, il s’agit implicitement d’un type référence, qui contredit lastructcontrainte. Supprimez la contrainte de classe ou lastructcontrainte. - Ne pas combiner
new()avecstruct(CS0451). Tous les types valeur (structs) ont implicitement un constructeur sans paramètre public, de sorte que lanew()contrainte est redondante lorsqu’elle est combinée avecstruct. Supprimez la contrainte lorsque vous utiliseznew()struct. - Remplacez par
delegateSystem.Delegateles clauses de contrainte (CS9011). Ledelegatemot clé est utilisé pour déclarer des types délégués, et non comme contrainte. Pour limiter un paramètre de type aux types délégués, utilisez-leSystem.Delegatecomme type de contrainte. Par exemple, remplacezwhere T : delegateparwhere T : System.Delegate.
L’exemple suivant montre l’ordre des contraintes correct :
using System;
// Primary constraint first, then interface constraints, then new()
class C<T> where T : class, IDisposable, new() { }
// struct doesn't need new() - it's implicit
class D<T> where T : struct, IComparable { }
// Delegate constraint using System.Delegate
class E<T> where T : System.Delegate { }
Pour plus d’informations, consultez Contraintes sur les paramètres de type.
Nombre d’arguments de type et utilisation
Les erreurs suivantes concernent la fourniture du nombre correct et du type d’arguments de type aux types et méthodes génériques :
- CS0224 : Une méthode avec vararg ne peut pas être générique, être dans un type générique ou avoir un paramètre params.
- CS0305 : L’utilisation du type générique nécessite des arguments de type N.
- CS0306 : Le type peut ne pas être utilisé comme argument de type.
- CS0307 : L’identificateur n’est pas une méthode générique. Si vous avez prévu une liste d’expressions, utilisez des parenthèses autour de l’expression.
- CS0308 : Impossible d’utiliser la méthode ou le type non générique avec des arguments de type.
- CS7002 : Utilisation inattendue d’un nom générique.
Pour corriger ces erreurs, vérifiez que vous fournissez le nombre exact d’arguments de type requis par la déclaration générique. Utilisez uniquement des types valides comme arguments de type. N’appliquez pas d’arguments de type à des constructions non génériques :
- Supprimez les paramètres de type générique ou contenant des déclarations de type générique des méthodes qui utilisent
__arglist(CS0224). Le__arglistmot clé est incompatible avec les génériques, car les mécanismes d’exécution de gestion des listes d’arguments variables sont en conflit avec la substitution de type requise pour les paramètres de type générique. Cette restriction s’applique également auparamsmot clé lorsqu’il est utilisé en combinaison avec des méthodes génériques ou des méthodes au sein de types génériques. - Indiquez le nombre exact d’arguments de type spécifiés dans la déclaration de type ou de méthode générique (CS0305). Chaque paramètre de type générique déclaré dans la définition doit avoir un argument de type correspondant lorsque le type générique est instancié. Le compilateur doit savoir quel type concret remplacer par chaque paramètre de type. Par exemple, si une classe est déclarée en tant que
class MyList<T>, vous devez fournir exactement un argument de type lors de son utilisation, par exemple, etMyList<int>nonMyList<int, string>. - Utilisez uniquement des types valides comme arguments de type (CS0306). Les types de pointeur, tels que
int*ouchar*, ne peuvent pas être utilisés comme arguments de type, car les types génériques nécessitent des types managés que le garbage collector peut suivre et les types de pointeurs ne sont pas gérés. Si vous devez utiliser des pointeurs dans un contexte générique, envisagez d’utiliserIntPtrou de restructurer votre code pour éviter de mélanger des génériques avec du code non sécurisé. - Supprimez la syntaxe de l'argument de type des constructions non génériques (CS0307, CS0308). Les arguments de type placés entre crochets angle (comme
<int>) peuvent uniquement être appliqués aux types et méthodes génériques qui déclarent des paramètres de type. Vous devez supprimer entièrement les arguments de type ou vous assurer que vous avez importé l’espace de noms qui contient la version générique du type. Par exemple,IEnumerator<T>nécessite la directiveusing System.Collections.Generic;, tandis queIEnumeratorest enSystem.Collections. - Supprimez les paramètres de type des déclarations qui ne prennent pas en charge les génériques (CS7002). Certaines constructions, telles que les énumérations, ne peuvent pas être génériques. Si vous avez besoin d’un conteneur générique pour les valeurs d’énumération, envisagez d’utiliser une classe ou un struct générique à la place.
Pour plus d’informations, consultez Paramètres de type générique et génériques.
Contraintes de constructeur
Les erreurs suivantes concernent la contrainte sur les new() paramètres de type générique :
-
CS0304 : Impossible de créer une instance du type de variable, car elle n’a pas la
new()contrainte. - CS0310 : Le type doit être un type non abstrait avec un constructeur sans paramètre public afin de l’utiliser comme paramètre dans le type générique ou la méthode.
- CS0417 : Identificateur : ne peut pas fournir d’arguments lors de la création d’une instance d’un type de variable.
Pour corriger ces erreurs, ajoutez la new() contrainte aux paramètres de type qui doivent être instanciés, vérifiez que les arguments de type ont des constructeurs sans paramètre public et évitez de passer des arguments lors de la construction d’instances de paramètres de type :
- Ajoutez la
new()contrainte à la déclaration de paramètre de type (CS0304). Lorsque vous utilisez l’opérateurnewpour créer une instance d’un paramètre de type au sein d’un type ou d’une méthode générique, le compilateur doit être en mesure de garantir que tout argument de type fourni au moment de l’exécution a un constructeur sans paramètre disponible. Lanew()contrainte fournit cette garantie au moment de la compilation, ce qui permet au compilateur de générer le code d’instanciation approprié. Par exemple, si vous avezclass C<T>avec un membreT t = new T();, vous devez changer la déclaration enclass C<T> where T : new(). - Vérifiez que les arguments de type utilisés avec
new()les paramètres de type contraint ont des constructeurs sans paramètre public (CS0310). Lorsqu’un type ou une méthode générique déclare unenew()contrainte sur un paramètre de type, tout type concret utilisé comme argument de type doit être non abstrait et doit fournir un constructeur sans paramètre public. Si un type possède uniquement des constructeurs non publics (tels queprivateouprotectedconstructeurs) ou ne possède que des constructeurs avec des paramètres, il ne peut pas satisfaire lanew()contrainte. Pour corriger cette erreur, ajoutez un constructeur sans paramètre public au type ou utilisez un argument de type différent qui en a déjà un. - Supprimez les arguments du constructeur lors de l’instanciation des paramètres de type (CS0417). La
new()contrainte garantit uniquement l’existence d’un constructeur sans paramètre. Vous ne pouvez donc pas passer d’arguments carnew T(arguments)le compilateur ne peut pas vérifier qu’un constructeur avec ces types de paramètres spécifiques existe sur les types qui sont remplacés parT. Si vous devez construire des instances avec des arguments spécifiques, envisagez d’utiliser des méthodes de fabrique, des modèles de fabrique abstraits ou des contraintes de classe de base ou d’interface spécifiques qui définissent le comportement de construction dont vous avez besoin.
Pour plus d’informations, consultez Contraintes sur les paramètres de type et la new() contrainte.
Satisfaction des contraintes et conversions
Les erreurs suivantes concernent les arguments de type qui ne satisfont pas aux contraintes des paramètres de type générique :
-
CS0311 : Le type ne peut pas être utilisé comme paramètre
Tde type dans le type générique ou la méthode. Il n’existe aucune conversion de référence implicite. - CS0312 : Le type ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Le type Nullable ne satisfait pas la contrainte.
- CS0313 : Le type ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Le type Nullable ne satisfait pas la contrainte. Les types nullables ne peuvent pas satisfaire à des contraintes d’interface.
- CS0314 : Le type ne peut pas être utilisé comme paramètre de type dans le type générique ou dans la méthode. Il n'y a pas de conversion de boxing ou de conversion de type paramétrique.
-
CS0315 : Le type ne peut pas être utilisé en tant que paramètre de type dans le type générique ou la méthode
TypeorMethod<T>. Il n’y a pas de conversion boxing.
Pour corriger ces erreurs, utilisez des arguments de type qui répondent à toutes les contraintes par le biais de conversions appropriées, assurez-vous que les classes dérivées répètent les contraintes de classe de base et comprenez que les types de valeurs nullables ont des exigences de contrainte spéciales :
- Modifiez l’argument de type en un qui a une conversion de référence implicite vers le type de contrainte (CS0311). Lorsqu’un paramètre de type a une contrainte telle que
where T : BaseType, tout argument de type doit pouvoir être converti enBaseTypepar une conversion de référence implicite ou par une conversion d'identité. L’argument de type doit êtreBaseTypelui-même, dériver deBaseType, ou implémenterBaseTypes’il s’agit d’une interface. Les conversions numériques implicites (deshortàint) ne répondent pas aux contraintes de paramètre de type générique, car ces conversions sont des conversions de valeurs, et non des conversions de référence. - Répétez les contraintes de paramètre de type de la classe de base dans toute déclaration de classe dérivée (CS0314). Lorsqu’une classe générique dérivée hérite d’une classe générique de base qui a des contraintes sur ses paramètres de type, la classe dérivée doit déclarer les mêmes contraintes sur ses paramètres de type correspondants. Vous devez répéter ces contraintes, car le compilateur doit vérifier que les arguments de type fournis à la classe dérivée répondent aux exigences de la classe de base. Par exemple, si vous avez
public class A<T> where T : SomeClass, toute classe dérivant de celle-ci doit être déclarée en tant quepublic class B<T> : A<T> where T : SomeClass. - Utilisez des types valeur non nullables ou modifiez le type de contrainte (CS0312, CS0313). Les types valeur nullables (par exemple
int?) sont distincts de leurs types valeur sous-jacents et ne répondent pas aux mêmes contraintes. Il n’existe aucune conversion implicite entreint?etint, et les types valeur nullable ne peuvent pas satisfaire aux contraintes d’interface, car le wrapper nullable lui-même n’implémente pas l’interface, même si le type de valeur sous-jacent le fait. Pour corriger ces erreurs, utilisez la forme non nullable du type valeur comme argument de type, ou ajustez votre contrainte pour accepterobjectou un type de référence nullable le cas échéant. - Vérifiez que les arguments de type répondent aux contraintes de type de référence ou de classe (CS0315). Lorsqu’un paramètre de type est limité à un type de classe (par exemple
where T : SomeClass), vous ne pouvez pas utiliser de type valeur (struct) comme argument de type, car il n’existe aucune conversion de boxing qui satisfait à la relation de contrainte. La contrainte nécessite un type de référence qui a une relation d’héritage ou d’implémentation avec le type de contrainte. Pour résoudre cette erreur, remplacez le struct par une classe si elle est sémantiquement appropriée, ou supprimez la contrainte de classe si le type générique peut fonctionner avec des types valeur.
Pour plus d’informations, consultez Contraintes sur les paramètres de type et conversions implicites.
Restrictions d’utilisation de type générique
Les erreurs suivantes concernent les restrictions relatives à l’utilisation des types génériques :
-
CS0403 : Impossible de convertir null en paramètre de type, car il peut s’agir d’un type valeur non nullable. Envisagez plutôt d’utiliser
default(T). -
CS0413 : Le paramètre de type ne peut pas être utilisé avec l’opérateur
as, car il n’a pas de contrainte de type de classe ni declasscontrainte. - CS0695 : Le type ne peut pas implémenter à la fois les deux interfaces, car elles peuvent se confondre pour certaines substitutions de paramètres de type.
- CS0698 : un type générique ne peut pas dériver du type, car il s’agit d’une classe d’attributs.
- CS8322 : Impossible de passer un argument avec un type dynamique à une fonction locale générique avec des arguments de type déduits.
- CS9338 : Accessibilité incohérente : le type est moins accessible que la classe.
Pour corriger ces erreurs, utilisez default plutôt que null pour les paramètres de type non contraints, ajoutez des contraintes de classe lors de l’utilisation de l’opérateur as, évitez les conflits d’unification d’interface, ne créez pas de classes d'attribut générique, et assurez-vous que les arguments de type correspondent à la visibilité de leurs membres hôtes :
- Remplacez
nullles affectations pardefault(T)ou ajoutez uneclasscontrainte (CS0403). Lorsque vous attribueznullun paramètre de type non contrainte, le compilateur ne peut pas garantir que l’argument de type est un type de référence qui accepte desnullvaleurs, car il peut s’agir d’un type valeur commeintoustruct, qui ne peut pas êtrenull. Pour résoudre cette erreur, utilisezdefault(T), qui fournit la valeur par défaut appropriée pour n’importe quel type (null pour les types référence, zéro ou vide pour les types valeur), ou ajoutez uneclasscontrainte au paramètre de type si vous avez spécifiquement besoin d’une sémantique de type référence et souhaitez autorisernullles affectations. - Ajoutez une
classcontrainte de type ou spécifique lors de l’utilisation de l’opérateuras(CS0413). L’opérateuraseffectue un cast de type sécurisé qui retournenullsi la conversion échoue, mais ce comportement est incompatible avec les types valeur, car les types valeur ne peuvent pas êtrenull. Lorsque vous utilisezasun paramètre de type non contrainte, le compilateur ne peut pas garantir que l’argument de type n’est pas un type valeur. Il rejette donc le code. Pour corriger cette erreur, ajoutez uneclasscontrainte ou une contrainte de type référence spécifique (parwhere T : SomeClassexemple) pour vous assurer que le paramètre de type est toujours un type de référence capable de gérer correctement lenullrésultat d’un cast ayant échoué. - Évitez d’implémenter la même interface générique plusieurs fois avec des paramètres de type qui pourraient unifier (CS0695). Lorsqu’une classe implémente une interface générique plusieurs fois avec différents paramètres de type (par exemple
class G<T1, T2> : I<T1>, I<T2>), il existe un risque que quelqu’un puisse l’instancier avec le même type pour les deux paramètres (G<int, int>), ce qui créerait un conflit, car la classe implémenterait effectivementI<int>deux fois. Pour résoudre cette erreur, implémentez l’interface une seule fois, restructurez vos paramètres de type pour empêcher l’unification ou utilisez des classes non génériques distinctes pour différentes spécialisations. - Supprimez les paramètres de type générique des classes d’attributs (CS0698).
Note
Cette erreur n’est pas générée dans les versions actuelles de C#, car les attributs génériques sont désormais pris en charge.
- Spécifiez explicitement des arguments de type lors de la transmission de valeurs dynamiques à des fonctions locales génériques (CS8322). Lorsque vous passez un
dynamicargument à une fonction locale générique, le compilateur ne peut pas déduire les arguments de type, car le type réel n’est pas connu tant que l’exécution n’est pas terminée. Pour corriger cette erreur, spécifiez explicitement l’argument de type (par exemple,LocalFunc<int>(d)), convertissez la valeur dynamique en type attendu ou utilisez une variable non dynamique. - Vérifiez que les arguments de type utilisés dans les signatures publiques ou protégées sont au moins aussi accessibles que le membre qui les utilise (CS9338). Un membre générique public ou protégé doit utiliser des arguments de type accessibles publiquement. Sinon, le code externe n’a pas pu référencer ou utiliser correctement la signature du membre. Par exemple, si vous avez
public class Container<T>oùTest un type interne, les assemblies externes peuvent voir leContainermais ne peuvent pas bien fonctionner avec lui car elles ne peuvent pas voirT. Pour corriger cette erreur, rendez l'argument de type public ou réduisez l'accessibilité du membre pour qu'elle corresponde à celle de l'argument de type.
Pour plus d’informations, consultez Contraintes sur les paramètres de type, les expressions de valeur par défaut et les attributs.
Types de contraintes valides
Les erreurs suivantes concernent l’utilisation de types non valides comme contraintes sur les paramètres de type générique :
- CS0405 : Contrainte dupliquée pour le paramètre de type.
- CS0702 : La contrainte ne peut pas être une classe spéciale.
- CS0703 : Accessibilité incohérente : le type de contrainte est moins accessible que la déclaration.
- CS0706 : Type de contrainte non valide. Un type utilisé comme contrainte doit être une interface, une classe non scellée ou un paramètre de type.
-
CS0717 :
static class: les classes statiques ne peuvent pas être utilisées comme contraintes.
Une contrainte doit être une interface, une classe non scellée ou un paramètre de type. Certains types ne sont pas valides en tant que contraintes en raison de leur signification particulière dans le système de type .NET ou parce qu’ils ne peuvent pas être hérités.
Pour corriger ces erreurs :
- Supprimez les contraintes dupliquées (CS0405). Chaque contrainte ne peut apparaître qu’une seule fois dans une clause de contrainte. Si vous avez
where T : I, I, supprimez le doublon. - N’utilisez pas de classes spéciales comme contraintes (CS0702). Les types Object, Arrayet ValueType ne peuvent pas être utilisés comme contraintes. Chaque type dérive déjà de
Object, donc la restreindre n'apporte aucune valeur.ArrayetValueTypesont des types de base abstraits qui ne peuvent pas être directement hérités. Si vous avez besoin d’un comportement de type tableau, utilisezIList<T>ouIEnumerable<T>à la place. - Vérifiez que les types de contraintes sont au moins aussi accessibles que le type générique (CS0703). Un type générique public ne peut pas avoir de contraintes à l’aide de types internes, car le code externe ne peut pas fournir d’arguments de type valides. Rendre le type de contrainte public ou réduire l’accessibilité du type générique.
- Utilisez uniquement des interfaces, des classes non scellées ou des paramètres de type en tant que contraintes (CS0706). Vous ne pouvez pas utiliser de tableaux, de classes scellées, de structs, d’énumérations ou d’autres types non valides comme contraintes. Si vous avez besoin d’un comportement spécifique, envisagez d’utiliser une interface que les types souhaités implémentent.
- N’utilisez pas de classes statiques comme contraintes (CS0717). Les classes statiques ne peuvent pas être étendues, car elles contiennent uniquement des membres statiques. Aucun type ne peut exister qui dérive d’une classe statique, ce qui le rend inutile en tant que contrainte. Utilisez plutôt une classe ou une interface non statique.
L’exemple suivant montre les types de contraintes valides :
public interface IMyInterface { }
public class MyBaseClass { }
// Valid: interface constraint
class A<T> where T : IMyInterface { }
// Valid: non-sealed class constraint
class B<T> where T : MyBaseClass { }
// Valid: type parameter constraint
class C<T, U> where T : U { }
Pour plus d’informations, consultez Contraintes sur les paramètres de type.
Conflits de contraintes et dépendances circulaires
Les erreurs suivantes concernent les conflits entre les contraintes ou les dépendances circulaires dans les déclarations de contrainte :
- CS0454 : dépendance de contrainte circulaire impliquant le paramètre de type 1 et le paramètre de type 2.
- CS0455 : Le paramètre de type hérite des contraintes conflictuelles.
Les contraintes ne peuvent pas créer de dépendances circulaires et les paramètres de type ne peuvent pas hériter de contraintes conflictuelles impossibles à satisfaire simultanément.
Pour corriger ces erreurs :
- Supprimez les dépendances de contrainte circulaire (CS0454). Un paramètre de type ne peut pas dépendre directement ou indirectement de lui-même par ses contraintes. Par exemple,
where T : U where U : Tcrée une dépendance circulaire, carTdépendUetUdépendTde . Arrêtez le cycle en supprimant l’une des contraintes. - Supprimez les contraintes héritées en conflit (CS0455). Un paramètre de type ne peut pas être contraint à plusieurs classes non liées, car C# ne prend pas en charge l’héritage de plusieurs classes. De même, il ne peut pas être contraint à la fois à
structet à un type de classe, car ces contraintes s’excluent mutuellement. Restructurez votre hiérarchie de type ou supprimez l’une des contraintes en conflit.
L’exemple suivant montre les problèmes :
// CS0454: Circular dependency - T depends on U and U depends on T
class Circular<T, U> where T : U where U : T { }
// CS0455: Conflicting constraints - U can't derive from both B and B2
public class B { }
public class B2 { }
public class G<T> where T : B
{
public class N<U> where U : B2, T { }
}
Pour plus d’informations, consultez Contraintes sur les paramètres de type.
Variance des paramètres de type
L’erreur suivante concerne les modificateurs de variance sur les paramètres de type générique :
- CS1961 : Variance non valide : le paramètre de type doit être validement variant sur le type.
Les modificateurs de variance (in pour contravariance, out pour covariance) contrôlent la façon dont vous utilisez les paramètres de type dans les déclarations d’interface et de délégué. Un paramètre de type covariant (out) ne peut apparaître que dans les positions de sortie (types de retour), tandis qu’un paramètre de type contravariant (in) ne peut apparaître que dans les positions d’entrée (types de paramètres).
Pour corriger cette erreur :
- Utilisez
out(covariant) pour les paramètres de type qui apparaissent uniquement dans les types de retour. La covariance permet d’utiliser un type plus dérivé où un type moins dérivé est attendu. - Utilisez
in(contravariant) pour les paramètres de type qui apparaissent uniquement dans les types de paramètres. La contravariance permet d’utiliser un type moins dérivé où un type plus dérivé est attendu. - Supprimez le modificateur de variance si le paramètre de type doit apparaître à la fois dans les positions d’entrée et de sortie.
L’exemple suivant montre une utilisation correcte et incorrecte de la variance :
// Incorrect: out T can't appear in input position
interface IWrong<out T>
{
void Method(T arg); // CS1961
}
// Correct: out T only in output positions
interface ICovariant<out T>
{
T GetValue();
}
// Correct: in T only in input positions
interface IContravariant<in T>
{
void Process(T arg);
}
// No modifier needed for both input and output
interface IInvariant<T>
{
T Transform(T arg);
}
Pour plus d’informations, consultez Covariance et Contravariance dans les génériques.