Résoudre les erreurs et les avertissements liés aux paramètres de type générique et aux arguments de type générique

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 qui n’est pas 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 » ne peut pas être utilisé avec des arguments de type.
  • 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 T de 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 de 'constraint'.
  • 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 de 'constraint'. 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 boxing ni conversion de paramètre de type de 'type' vers 'constraint'.
  • CS0315: Le type ne peut pas être utilisé comme argument de type T dans le type générique ou la méthode. Il n’existe aucune conversion d’empaquetage de 'type' vers 'constraint'.
  • CS0401 : La new() contrainte doit être la dernière contrainte restrictive 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.
  • CS0406 : La contrainte de type de classe 'contrainte' doit être antérieure à d’autres contraintes.
  • CS0409 : une clause de contrainte a déjà été spécifiée pour le paramètre de type « paramètre de type ». Toutes les contraintes d’un paramètre de type doivent être spécifiées dans une clause where unique.
  • CS0411 : Les arguments de type de la méthode 'method' ne peuvent pas être déduits de l’utilisation. Essayez de spécifier explicitement les arguments 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 de class contrainte.
  • 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, notnull et default ne 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 class ou struct.
  • CS0451 : La new() contrainte ne peut pas être utilisée avec la struct contrainte.
  • CS0452 : le type 'nom de type' doit être un type de référence pour l’utiliser comme paramètre 'nom de paramètre' dans le type générique ou la méthode 'generic'.
  • CS0453 : Le type 'type name' doit être un type valeur non Nullable pour l’utiliser comme paramètre 'nom de paramètre' dans le type générique ou la méthode 'generic'.
  • 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 « constraint1 » et « constraint2 ».
  • CS0456 : Le paramètre de type « paramètre de type 1 » a la contrainte « struct » de sorte que « paramètre de type 1 » ne peut pas être utilisé comme contrainte pour « paramètre de type 2 ».
  • CS0693 : Le paramètre de type 'paramètre de type' a le même nom que le paramètre de type du type externe 'type'.
  • CS0694 : Le paramètre de type a le même nom que le type conteneur ou la méthode.
  • CS0695 : « type » ne peut pas implémenter à la fois « interface1 » et « interface2 », car ils 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.
  • CS0699 : 'generic' ne définit pas le paramètre de type 'identifier'.
  • CS0701 : 'identificateur' n’est pas une contrainte valide. Un type utilisé comme contrainte doit être une interface, une classe non scellée ou un 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.
  • CS0704 : Impossible d’effectuer une recherche de membre non virtuel dans « type », car il s’agit d’un paramètre de type.
  • 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.
  • CS0718 : 'type' : les types statiques ne peuvent pas être utilisés comme arguments de type.
  • CS1720 : L’expression provoque toujours une exception System.NullReferenceException, car la valeur par défaut de « type générique » est Null.
  • CS1763 : 'parameter' est de type 'type'. Une valeur de paramètre par défaut d’un type référence autre que la chaîne ne peut être initialisée qu’avec null.
  • CS1948 : La variable de plage 'name' ne peut pas avoir le même nom qu’un paramètre de type de méthode.
  • CS1960 : modificateur de variance non valide. Seuls les paramètres d’interface et de type délégué peuvent être spécifiés en tant que variante.
  • CS1961 : Variance non valide : le paramètre de type doit être covariantment valide sur « type ». 'type parameter' est contravariant.
  • CS3024 : Le type de contrainte 'type' n’est pas conforme CLS.
  • 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.
  • CS8375 : La contrainte 'new()' ne peut pas être utilisée avec la contrainte 'non managée'.
  • CS8377: Le type 'type' doit être un type de valeur non nullable, ainsi que tous les champs à n’importe quel niveau d’imbrication, pour pouvoir l’utiliser comme paramètre 'parameter' dans le type générique ou la méthode 'generic'.
  • CS8379 : Le paramètre de type « paramètre de type 1 » a la contrainte « non managée » de sorte que « paramètre de type 1 » ne peut pas être utilisé comme contrainte pour « paramètre de type 2 ».
  • CS8380 : 'type' : ne peut pas spécifier à la fois une classe de contrainte et la contrainte 'unmanaged'.
  • CS8387 : Le paramètre de type 'paramètre de type' a le même nom que le paramètre de type de la méthode externe 'method'.
  • CS8389 : omettre l’argument de type n’est pas autorisé dans le contexte actuel.
  • CS8427 : Les énumérations, les classes et les structures ne peuvent pas être déclarées dans une interface qui a un paramètre de type « in » ou « out ».
  • CS8665: La méthode 'method' spécifie une contrainte 'class' pour le paramètre de type 'type parameter', mais le paramètre de type correspondant 'type parameter' de la méthode substituée ou implémentée explicitement 'method' n’est pas un type de référence.
  • CS8666: La méthode 'method' spécifie une contrainte 'struct' pour le paramètre de type 'type parameter', mais le paramètre de type correspondant 'type parameter' de la méthode substituée ou implémentée explicitement 'method' n’est pas un type valeur non nullable.
  • CS8822 : La méthode 'method' spécifie une contrainte 'default' pour le paramètre de type 'paramètre de type', mais le paramètre de type correspondant 'paramètre type' de la méthode substituée ou explicitement implémentée 'method' est limitée à un type référence ou à un type valeur.
  • CS8823 : La contrainte « par défaut » est valide uniquement sur les méthodes de remplacement et d’implémentation d’interface explicite.
  • CS8893 : 'type' n’est pas un type de convention d’appel valide pour 'UnmanagedCallersOnly'.
  • CS8894 : Impossible d’utiliser « type » comme paramètre ou type de retour sur une méthode attribuée avec « UnmanagedCallersOnly ».
  • CS8895 : Les méthodes attribuées avec « UnmanagedCallersOnly » ne peuvent pas avoir de paramètres de type générique et ne peuvent pas être déclarées dans un type générique.
  • CS8896 : « UnmanagedCallersOnly » ne peut être appliqué qu’à des fonctions statiques non abstraites, non virtuelles ou statiques.
  • CS9011 : Le mot clé delegate ne peut pas être utilisé comme contrainte. Tu veux dire System.Delegate?
  • CS9012 : mot clé recordinattendu . Tu veux dire record struct ou record class?
  • CS9338 : Accessibilité incohérente : le type est moins accessible que la classe.

Déclaration de paramètre de type et nommage

  • 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 qui n’est pas 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.
  • CS0693 : Le paramètre de type 'paramètre de type' a le même nom que le paramètre de type du type externe 'type'.
  • CS0694 : Le paramètre de type a le même nom que le type conteneur ou la méthode.
  • CS0699 : 'generic' ne définit pas le paramètre de type 'identifier'.
  • CS1948 : La variable de plage 'name' ne peut pas avoir le même nom qu’un paramètre de type de méthode.
  • CS8387 : Le paramètre de type 'paramètre de type' a le même nom que le paramètre de type de la méthode externe 'method'.
  • CS9012 : mot clé recordinattendu . Tu veux dire record struct ou record class?

Ces erreurs concernent la façon dont vous déclarez et nommez des paramètres de type dans les types et méthodes génériques. Les noms de paramètres de type doivent être des identificateurs valides, ne doivent pas entrer en conflit avec d’autres identificateurs dans l’étendue et doivent apparaître dans la liste des paramètres de type de la déclaration.

  • Supprimez la clause de contrainte des déclarations non génériques (CS0080). La where clause ne peut être utilisée que sur les types génériques et les méthodes qui déclarent des paramètres de type. Si vous devez appliquer des contraintes, commencez par ajouter des paramètres de type à votre déclaration de type ou de méthode.
  • 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 (commeT, ou TKeyTValue) plutôt que de types concrets (comme int ou string). 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é.
  • Renommez les paramètres de type, les variables locales, les paramètres ou les variables de plage pour éviter les conflits de nommage (CS0412, CS0694, CS1948). Les noms de paramètres de type ne peuvent pas masquer les identificateurs dans la même étendue et ne peuvent pas correspondre au nom du type ou de la méthode conteneur. Les variables de plage LINQ ne peuvent pas également réutiliser le nom du paramètre de type d’une méthode. Ces conflits créent une ambiguïté sur l'identificateur qui est référencé.
  • Utilisez un autre nom pour les paramètres de type interne qui ombrent les paramètres externes (CS0693, CS8387). Lorsqu’un membre générique (tel qu’une méthode ou un type imbriqué) se trouve à l’intérieur d’une classe ou d’une méthode générique, le paramètre de type interne n’est pas nécessairement identique à celui externe. Leur donner le même nom crée une confusion quant au paramètre de type référencé. Utilisez un nom distinct pour le paramètre de type interne.
  • Vérifiez que tous les paramètres de type dans les clauses de contrainte sont déclarés dans la liste des paramètres de type (CS0699). Une where clause ne peut référencer que les paramètres de type qui apparaissent dans la déclaration générique. Si le nom de la where clause ne correspond à aucun paramètre de type déclaré, recherchez des fautes de frappe ou des fautes d’orthographe.
  • 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 struct ou (ou simplement record pour un type référence). Le record mot clé seul ne peut pas apparaître dans des positions où le compilateur attend une syntaxe de déclaration différente.

Pour plus d’informations, consultez Paramètres de type générique et génériques.

Déclaration et ordonnancement des contraintes

  • CS0401 : La new() contrainte doit être la dernière contrainte restrictive spécifiée.
  • CS0406 : La contrainte de type de classe 'contrainte' doit être antérieure à d’autres contraintes.
  • CS0409 : une clause de contrainte a déjà été spécifiée pour le paramètre de type « paramètre de type ». Toutes les contraintes d’un paramètre de type doivent être spécifiées dans une clause where unique.
  • CS0449 : Les contraintes class, struct, unmanaged, notnull et default ne 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 ou class.
  • CS0451 : La new() contrainte ne peut pas être utilisée avec la struct contrainte.
  • CS8375 : La contrainte 'new()' ne peut pas être utilisée avec la contrainte 'non managée'.
  • CS8380 : 'type' : ne peut pas spécifier à la fois une classe de contrainte et la contrainte 'unmanaged'.
  • CS9011 : Le mot clé delegate ne peut pas être utilisé comme contrainte. Tu veux dire System.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, puis une contrainte de type de classe, suivie de contraintes d’interface, et enfin la contrainte du new() constructeur. Certaines contraintes s’excluent mutuellement et ne peuvent pas être combinées. Toutes les contraintes d’un paramètre de type unique doivent apparaître dans une clause unique where .

  • Placez la new() contrainte à la fin de la liste de contraintes (CS0401). La new() contrainte doit apparaître après toutes les autres contraintes. Par exemple, remplacez where T : new(), IDisposable par where T : IDisposable, new().
  • Placez la contrainte de type de classe avant les contraintes d’interface (CS0406). Lorsque vous limitez un paramètre de type à une classe de base spécifique avec des interfaces, la classe doit apparaître en premier. Par exemple, remplacez where T : IDisposable, MyBaseClass par where T : MyBaseClass, IDisposable.
  • Combinez toutes les contraintes d’un paramètre de type dans une clause unique where (CS0409). Vous ne pouvez pas utiliser plusieurs where clauses pour le même paramètre de type. Fusionnez-les dans une clause : passez where T : I where T : new() à where T : I, new(). Plusieurs where clauses sont valides uniquement lorsqu’elles ciblent des paramètres de type différents.
  • 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, notnull ou default, et il doit apparaître en premier dans la liste de contraintes. Les contraintes class et struct sont mutuellement exclusives, tout comme class et unmanaged.
  • Ne combinez pas de contrainte de classe spécifique avec class, structou unmanaged (CS0450, CS8380). Si un paramètre de type est contraint à un type de classe spécifique, il s’agit implicitement d’un type de référence, ce qui est en contradiction avec la contrainte struct ou unmanaged. Supprimez la contrainte de classe ou la contrainte primaire.
  • Ne pas combiner new() avec struct ou unmanaged (CS0451, CS8375). Tous les types valeur ont implicitement un constructeur sans paramètre public, de sorte que la new() contrainte est redondante lorsqu’elle est combinée avec struct. La même chose s’applique à unmanaged, ce qui implique struct. Supprimez la new() contrainte.
  • Remplacez par delegateSystem.Delegate les clauses de contrainte (CS9011). Le delegate mot 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-le System.Delegate comme type de contrainte.

Pour plus d’informations, consultez Contraintes sur les paramètres de type.

Types de contraintes valides

  • CS0405 : Contrainte dupliquée pour le paramètre de type.
  • CS0701 : 'identificateur' n’est pas une contrainte valide. Un type utilisé comme contrainte doit être une interface, une classe non scellée ou un 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 : Classe statique : les classes statiques ne peuvent pas être utilisées comme contraintes.
  • CS3024 : Le type de contrainte 'type' n’est pas conforme CLS.

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.

  • 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.
  • Utilisez uniquement des types non scellés comme contraintes (CS0701). Les classes scellées, les structs et les énumérations ne peuvent pas être héritées, de sorte qu’elles ne servent pas de contraintes. Utilisez une interface que les types souhaités implémentent ou utilisez une classe de base non scellée.
  • 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. Array et ValueType sont des types de base abstraits qui ne peuvent pas être directement hérités. Si vous avez besoin d’un comportement de type tableau, utilisez IList<T> ou IEnumerable<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. 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 dériver d’une classe statique, ce qui en fait inutile comme contrainte.
  • Utilisez un type conforme CLS pour la contrainte de type (CS3024). Lorsqu’un assembly est marqué avec [assembly: CLSCompliant(true)], le fait d’utiliser un type non conforme à la CLS comme contrainte de type générique peut empêcher du code écrit dans certains langages d’utiliser votre classe générique.

Pour plus d’informations, consultez Contraintes sur les paramètres de type.

Satisfaction des contraintes et conversions

  • CS0311 : Le type ne peut pas être utilisé comme paramètre T de 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 ne peut pas être utilisé comme paramètre de type dans le type générique ou la méthode. Le type nullable ne répond pas à la contrainte de « 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 répond pas à la contrainte de « 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 d’empaquetage ni conversion d’un paramètre de type de 'type' vers 'constraint'.
  • CS0315: Le type ne peut pas être utilisé comme paramètre de type T dans le type ou la méthode générique. Il n’existe aucune conversion de boxing entre 'type' et 'constraint'.
  • CS0452 : le type 'nom de type' doit être un type de référence pour l’utiliser comme paramètre 'nom de paramètre' dans le type générique ou la méthode 'generic'.
  • CS0453 : Le type 'type name' doit être un type valeur non Nullable pour l’utiliser comme paramètre 'nom de paramètre' dans le type générique ou la méthode 'generic'.
  • CS8377 : Le type 'type' doit être un type de valeur non nullable, ainsi que tous ses champs, à n’importe quel niveau d’imbrication, pour être utilisé comme paramètre 'parameter' dans le type générique ou la méthode 'generic'.

Ces erreurs se produisent lorsqu’un argument de type ne répond pas aux contraintes déclarées sur un paramètre de type générique. L’argument de type doit avoir les conversions correctes, les relations d’héritage et les propriétés structurelles pour correspondre à toutes les contraintes.

  • 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 en BaseType par une conversion de référence implicite ou par une conversion d'identité. Les conversions numériques implicites (de short à int) ne répondent pas aux contraintes de paramètre de type générique.
  • 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. 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. Utilisez la forme non nullable du type valeur comme argument de type.
  • 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 contrainte, la classe dérivée doit déclarer les mêmes contraintes sur ses paramètres de type correspondants.
  • 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 contraint à un type de classe, vous ne pouvez pas utiliser un type valeur (structure) comme argument de type, car il n’existe aucune conversion d’empaquetage permettant de satisfaire à la contrainte. Utilisez un type de référence qui hérite ou implémente la contrainte.
  • Utilisez un type de référence comme argument de type lorsque la class contrainte est spécifiée (CS0452). Types valeur tels que struct ou int ne peuvent pas satisfaire à une class contrainte. Modifiez l’argument de type en type référence ou supprimez la class contrainte si le type générique peut fonctionner avec des types valeur.
  • Utilisez un type valeur non nullable comme argument de type lorsque la struct contrainte est spécifiée (CS0453). Les types référence, les types valeur nullable (int?) et d’autres types non-valeur ne peuvent pas satisfaire à une struct contrainte. Utilisez un type valeur concret non nullable, comme int, double ou un struct défini par l’utilisateur.
  • Utilisez un type dont les champs sont tous des types non managés lorsque la unmanaged contrainte est spécifiée (CS8377). La contrainte unmanaged requiert un type de valeur non nullable dont chaque champ, à chaque niveau d’imbrication, est également d’un type non managé. Les types contenant des champs de type référence ou des paramètres de type générique qui ne sont pas connus pour être non gérés ne répondent pas à cette contrainte.

Pour plus d’informations, consultez Contraintes sur les paramètres de type.

Conflits de contraintes et dépendances circulaires

  • 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 « constraint1 » et « constraint2 ».
  • CS0456 : Le paramètre de type « paramètre de type 1 » a la contrainte « struct » de sorte que « paramètre de type 1 » ne peut pas être utilisé comme contrainte pour « paramètre de type 2 ».
  • CS8379 : Le paramètre de type « paramètre de type 1 » a la contrainte « non managée » de sorte que « paramètre de type 1 » ne peut pas être utilisé comme contrainte pour « paramètre de type 2 ».

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. Les contraintes de type valeur (struct et unmanaged) sont implicitement scellées, de sorte qu’elles ne peuvent pas être utilisées comme contraintes sur d’autres paramètres de type.

  • 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 : T crée une dépendance circulaire. 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 avoir à la fois struct et un type de classe comme contraintes. Restructurez votre hiérarchie de type ou supprimez l’une des contraintes en conflit.
  • N’utilisez pas un paramètre de type soumis à la contrainte struct ou à la contrainte unmanaged comme contrainte pour un autre paramètre de type (CS0456, CS8379). Les contraintes de type valeur sont implicitement scellées, de sorte qu’aucun autre type ne peut dériver d’eux. Pour résoudre cette erreur, placez le type valeur ou la contrainte non managée directement sur le deuxième paramètre de type au lieu de le limiter indirectement par le biais du premier paramètre de type.

Pour plus d’informations, consultez Contraintes sur les paramètres de type.

Règles de contrainte de remplacement et d’implémentation

  • CS8665: La méthode 'method' spécifie une contrainte 'class' pour le paramètre de type 'type parameter', mais le paramètre de type correspondant 'type parameter' de la méthode substituée ou explicitement implémentée 'method' n’est pas un type de référence.
  • CS8666: La méthode 'method' spécifie une contrainte 'struct' pour le paramètre de type 'type parameter', mais le paramètre de type correspondant 'type parameter' de la méthode 'method' redéfinie ou implémentée explicitement n’est pas un type valeur non nullable.
  • CS8822 : La méthode 'method' spécifie la contrainte 'default' pour le paramètre de type 'type parameter', mais le paramètre de type correspondant 'type parameter' de la méthode substituée ou explicitement implémentée 'method' est limité à un type de référence ou à un type de valeur.
  • CS8823 : La contrainte « par défaut » est valide uniquement sur les méthodes de remplacement et d’implémentation d’interface explicite.

Lorsque vous substituez une méthode virtuelle ou implémentez explicitement une méthode d’interface, les contraintes sur les paramètres de type de la méthode de substitution doivent être compatibles avec les contraintes de la méthode de base. La contrainte default est un modificateur spécial utilisé uniquement dans les scénarios de redéfinition et d’implémentation explicite d’interface pour indiquer qu’un paramètre de type n’a ni contrainte class ni contrainte struct.

  • Vérifiez que les contraintes de la méthode de substitution correspondent aux contraintes de la méthode de base (CS8665, CS8666). Une substitution ne peut pas ajouter de class contrainte si le paramètre de type correspondant de la méthode de base n’est pas limité à un type de référence. De même, il ne peut pas ajouter de struct contrainte si le paramètre de type de la méthode de base n’est pas limité à un type valeur. Le remplacement doit être compatible avec la déclaration de base.
  • Utilisez la default contrainte uniquement lorsque le paramètre de type de la méthode de base n’est pas contraint (CS8822). La default contrainte indique que le paramètre de type n’a ni classstruct contrainte. Vous ne pouvez pas appliquer default si le paramètre de type correspondant de la méthode remplacée comporte déjà une contrainte class ou struct.
  • Utilisez la contrainte default uniquement sur les méthodes de substitution ou d’implémentation explicite d’interface (CS8823). La default contrainte n’est pas valide sur les déclarations de méthode régulières. Il existe spécifiquement pour lever toute ambiguïté lors de la redéfinition d’une méthode dont la classe de base avait un paramètre de type sans contrainte, et vous devez indiquer que la redéfinition le laisse également sans contrainte.

Pour plus d’informations, consultez Contraintes sur les paramètres de type et la default contrainte.

Contraintes de constructeur

  • 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.

Ces erreurs concernent la new() contrainte et l’instanciation des paramètres de type avec l’opérateur new .

  • Ajoutez la new() contrainte aux paramètres de type que vous devez instancier (CS0304). Lorsque vous utilisez new T() à l’intérieur d’un type ou d’une méthode générique, le compilateur doit garantir que n’importe quel argument de type possède un constructeur sans paramètre. La new() contrainte fournit cette garantie.
  • Vérifiez que les arguments de type ont des constructeurs sans paramètre public (CS0310). Lorsqu’un paramètre de type a la new() contrainte, tout type concret utilisé comme argument de type doit être non abstrait et doit fournir un constructeur sans paramètre public. Les types avec uniquement des constructeurs privés, protégés ou paramétrables ne peuvent pas satisfaire la new() contrainte.
  • Supprimez les arguments du constructeur lors de l’instanciation des paramètres de type (CS0417). La new() contrainte garantit uniquement un constructeur sans paramètre. Vous ne pouvez pas passer d’arguments à new T(arguments). Si vous devez construire des instances avec des arguments spécifiques, envisagez d’utiliser un modèle de fabrique ou une contrainte d’interface qui définit le comportement de construction.

Pour plus d’informations, consultez Contraintes sur les paramètres de type et la new() contrainte.

Nombre d’arguments de type et utilisation

  • 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 » ne peut pas être utilisé avec des arguments de type.
  • 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.
  • CS8389 : omettre l’argument de type n’est pas autorisé dans le contexte actuel.

Ces erreurs concernent la fourniture du nombre correct et du type d’arguments aux types et méthodes 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 __arglist mot 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.
  • Indiquez le nombre exact d’arguments de type spécifiés dans la déclaration générique (CS0305). Chaque paramètre de type générique de la définition doit avoir un argument de type correspondant lorsque le type générique est instancié.
  • Utilisez uniquement des types valides comme arguments de type (CS0306). Les types de pointeur (tels que int* ou char*) 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.
  • Supprimez la syntaxe de l'argument de type des constructions non génériques (CS0307, CS0308). Les arguments de type placés entre crochets d’angle ne peuvent être appliqués qu’aux types génériques et aux méthodes qui déclarent des paramètres de type. Vérifiez que vous avez importé l’espace de noms qui contient la version générique du type.
  • 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.
  • Fournissez explicitement tous les arguments de type requis (CS8389). Dans certains contextes, par exemple lors de l’utilisation de l’opérateur typeof ou de la création de délégués, vous devez fournir tous les arguments de type et ne pouvez pas les omettre. Par exemple, utilisez typeof(List<int>) plutôt que de tenter d’omettre l’argument de type.

Pour plus d’informations, consultez Paramètres de type générique et génériques.

Inférence des arguments de type

  • CS0411 : Les arguments de type de la méthode 'method' ne peuvent pas être déduits de l’utilisation. Essayez de spécifier explicitement les arguments de type.

Cette erreur se produit lorsque vous appelez une méthode générique sans fournir explicitement les arguments de type et que le compilateur ne peut pas déduire les arguments de type que vous envisagez. Le compilateur déduit les arguments de type à partir des types des arguments de la méthode que vous passez lors de l’appel.

  • Spécifiez explicitement les arguments de type entre crochets (CS0411). Si le compilateur ne peut pas déterminer les arguments de type des arguments de méthode, fournissez-les directement. Par exemple, remplacez G() par G<int>(). Cette erreur se produit généralement lorsqu’une méthode générique n’a aucun paramètre à partir duquel déduire le type, ou lorsqu’un null argument est passé et que le compilateur ne peut pas déterminer le type prévu.

Pour plus d’informations, consultez Méthodes génériques.

Variance des paramètres de type

  • CS1960 : modificateur de variance non valide. Seuls les paramètres d’interface et de type délégué peuvent être spécifiés en tant que variante.
  • CS1961 : Variance non valide : le paramètre de type doit être covariantment valide sur « type ». 'type parameter' est contravariant.
  • CS8427 : Les énumérations, les classes et les structures ne peuvent pas être déclarées dans une interface qui a un paramètre de type « in » ou « out ».

Les modificateurs de variance (in pour la contravariance, out pour la covariance) contrôlent la façon dont vous pouvez utiliser les paramètres de type dans les déclarations d’interface et de délégué. Seules les interfaces et les délégués prennent en charge la variance. 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).

  • Utilisez des modificateurs de variance uniquement sur les paramètres d’interface et de type délégué (CS1960). Les classes, les structs et d’autres déclarations de type ne prennent pas en charge les modificateurs de variance. Seules les déclarations interface et delegate peuvent utiliser in ou out dans leurs paramètres de type.
  • Utilisez out (covariant) pour les paramètres de type qui apparaissent uniquement dans les types de retour et in (contravariant) pour les paramètres de type qui apparaissent uniquement dans les types de paramètres (CS1961). Si le paramètre de type doit apparaître à la fois dans les positions d’entrée et de sortie, supprimez le modificateur de variance.
  • Ne déclarez pas d’énumérations, de classes ou de structures à l’intérieur d’une interface variant (CS8427). Les déclarations de types imbriquées dans une interface qui comporte des paramètres de type in ou out ne sont pas autorisées, car elles pourraient enfreindre les règles de sûreté de la variance. Déplacez le type imbriqué en dehors de la déclaration d’interface.

Pour plus d’informations, consultez Covariance et Contravariance dans les génériques.

Restrictions d’utilisation de type générique

  • 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 de class contrainte.
  • CS0695 : « type » ne peut pas implémenter à la fois « interface1 » et « interface2 », car ils 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.
  • CS0704 : Impossible d’effectuer une recherche de membre non virtuel dans « type », car il s’agit d’un paramètre de type.
  • CS0718 : 'type' : les types statiques ne peuvent pas être utilisés comme arguments de type.
  • CS1720 : L’expression provoque toujours une exception System.NullReferenceException, car la valeur par défaut de « type générique » est Null.
  • CS1763 : 'parameter' est de type 'type'. Une valeur de paramètre par défaut d’un type référence autre que la chaîne ne peut être initialisée qu’avec null.
  • 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.

Ces erreurs concernent des restrictions sur la façon dont les types génériques et les paramètres de type peuvent être utilisés dans les expressions, l’héritage et l’accès aux membres.

  • Remplacez null les affectations par default(T) ou ajoutez une class contrainte (CS0403). Lorsque vous attribuez null un paramètre de type non contrainte, le compilateur ne peut pas garantir que l’argument de type est un type référence. Utilisez default(T), qui fournit la valeur par défaut appropriée pour n’importe quel type, ou ajoutez une contrainte si vous avez spécifiquement besoin d’une class sémantique de type référence.
  • Ajoutez une class contrainte de type ou spécifique lors de l’utilisation de l’opérateur as (CS0413). L’opérateur as retourne null si la conversion échoue, mais les types valeur ne peuvent pas être null. Ajoutez une class contrainte pour vous assurer que le paramètre de type est toujours un type référence.
  • É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 class G<T1, T2> : I<T1>, I<T2>exemple), l’instanciation avec le même type pour les deux paramètres créerait un conflit. Implémentez l’interface une seule fois ou restructurez-la pour empêcher l’unification.
  • Supprimez les paramètres de type générique des classes d’attributs (CS0698). Cette erreur n’est plus produite dans les versions actuelles de C#, car les attributs génériques sont désormais pris en charge.
  • Utilisez le type de contrainte concret au lieu du paramètre de type pour l’accès membre imbriqué (CS0704). Vous ne pouvez pas accéder aux types imbriqués ou aux membres non virtuels via un paramètre de type. Au lieu de T.InnerType, utilisez directement le type de contrainte connu, tel que BaseClass.InnerType.
  • N’utilisez pas de types statiques comme arguments de type (CS0718). Les types statiques ne peuvent pas être instanciés et ne peuvent pas être utilisés comme arguments génériques. Supprimez le type statique de l’argument générique.
  • Évitez d’appeler des membres d’instance sur default(T) lorsque T est contraint à un type référence (CS1720). Lorsque T a une contrainte class, default(T) est null, donc appeler des membres d’instance sur celui-ci lève toujours NullReferenceException. Ajoutez une vérification null avant d’appeler des membres ou restructurez le code pour éviter d’utiliser default(T) directement.
  • Utilisez null comme valeur de paramètre par défaut pour les paramètres facultatifs dont le type est un type de référence (CS1763). Si une méthode générique a un paramètre de type T et T est un type de référence, remplacez default(U) par null car les paramètres facultatifs par défaut doivent être des constantes au moment de la compilation et default(T) ne corrige pas cette exigence.
  • 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 dynamic argument à une fonction locale générique, le compilateur ne peut pas déduire les arguments de type. Spécifiez explicitement l’argument de type ou castez la valeur dynamique.
  • Vérifiez que les arguments de type utilisés dans les signatures publiques ou protégées ont une accessibilité au moins équivalente à celle du membre (CS9338). Un membre générique public doit utiliser des arguments de type accessibles publiquement. Rendez l’argument de type public, ou réduisez l’accessibilité du membre.

Pour plus d’informations, consultez Contraintes sur les paramètres de type et les expressions de valeur par défaut.

UnmanagedCallersOnly restrictions

  • CS8893 : 'type' n’est pas un type de convention d’appel valide pour 'UnmanagedCallersOnly'.
  • CS8894 : Impossible d’utiliser « type » comme paramètre ou type de retour sur une méthode attribuée avec « UnmanagedCallersOnly ».
  • CS8895 : Les méthodes attribuées avec « UnmanagedCallersOnly » ne peuvent pas avoir de paramètres de type générique et ne peuvent pas être déclarées dans un type générique.
  • CS8896 : « UnmanagedCallersOnly » ne peut être appliqué qu’à des fonctions statiques non abstraites, non virtuelles ou statiques.

L’attribut UnmanagedCallersOnlyAttribute marque les méthodes que le code non managé peut appeler. Ces méthodes ont des exigences strictes, car le runtime doit gérer la transition entre les conventions d’appel managées et non managées.

  • Utilisez uniquement les types de convention d’appel valides dans l’attribut UnmanagedCallersOnly (CS8893). La propriété CallConvs de l’attribut accepte uniquement les types de convention d’appel reconnus de l’espace de noms System.Runtime.CompilerServices.
  • Utilisez uniquement des types blittables en tant que types de paramètre et de retour (CS8894). Les méthodes marquées avec UnmanagedCallersOnly ne peuvent pas utiliser de types managés (tels que string ou object) comme types de paramètres ou de retour, car les appelants non managés ne peuvent pas gérer les références collectées par le ramasse-miettes.
  • Supprimez les paramètres de type générique des UnmanagedCallersOnly méthodes et ne les déclarez pas dans les types génériques (CS8895). Les conventions d’appel non managées ne prennent pas en charge les génériques, car le runtime ne peut pas déterminer la convention d’appel correcte pour les substitutions de types génériques.
  • Appliquez UnmanagedCallersOnly uniquement aux méthodes statiques, non abstraites, non virtuelles ou aux fonctions locales statiques (CS8896). Les méthodes d’instance, les méthodes abstraites et les méthodes virtuelles ne peuvent pas être marquées avec UnmanagedCallersOnly , car les appelants non managés ne peuvent pas effectuer les mécanismes de répartition dont ces méthodes ont besoin.

Pour plus d’informations, consultez UnmanagedCallersOnlyAttribute.