Erreurs et avertissements liés aux déclarations de propriétés

Vous pouvez rencontrer les erreurs suivantes liées aux déclarations de propriétés :

  • CS0200 : La propriété ou l'indexeur 'property' ne peut pas être assignée -- il est en lecture seule
  • CS0273 : Le modificateur d’accessibilité de l’accesseur ’property_accessor’ doit être plus restrictif que la propriété ou l’indexeur ’property’
  • CS0274 : Impossible de spécifier des modificateurs d’accessibilité pour les deux accesseurs de la propriété ou de l’indexeur 'property'
  • CS0275 : « accesseur » : les modificateurs d’accessibilité peuvent ne pas être utilisés sur les accesseurs d’une interface
  • CS0276 : 'property' : les modificateurs d’accessibilité sur les accesseurs peuvent uniquement être utilisés si la propriété ou l’indexeur a à la fois un accesseur get et un accesseur set
  • CS0442 : 'property' : les propriétés abstraites ne peuvent pas avoir d’accesseurs privés
  • CS0544 : 'property' : impossible de remplacer, car 'member' n’est pas une propriété
  • CS0545 : ’function’ : substitution impossible, car ’property’ n’a pas d’accesseur get substituable
  • CS0546 : ’accesseur’ : substitution impossible, car ’propriété’ n’a pas d’accesseur set substituable
  • CS0547 : 'property' : propriété ou indexeur ne peut pas avoir de type void
  • CS0548 : ’property’ : la propriété ou l’indexeur doit posséder au moins un accesseur
  • CS0571 : 'function' : impossible d’appeler explicitement l’opérateur ou l’accesseur
  • CS0610 : Champ ou propriété ne peut pas être de type 'type'
  • CS0840 : « Nom de propriété » doit déclarer un corps, car il n’est pas marqué comme abstrait ou extern. Les propriétés implémentées automatiquement doivent définir les accesseurs get et set.
  • CS1014 : Accesseur get ou set attendu
  • CS1043 : { ou ; attendu
  • CS1715 : 'type' : type doit être 'type' pour correspondre au membre substitué 'member'
  • CS8050 : Seules les propriétés implémentées automatiquement, ou les propriétés qui utilisent le mot clé « field », peuvent avoir des initialiseurs.
  • CS8051 : Les propriétés implémentées automatiquement doivent avoir des accesseurs.
  • CS8053 : Les propriétés d’instance dans les interfaces ne peuvent pas avoir d’initialiseurs.
  • CS8080 : Les propriétés implémentées automatiquement doivent remplacer tous les accesseurs de la propriété substituée.
  • CS8145 : Les propriétés implémentées automatiquement ne peuvent pas retourner par référence
  • CS8147 : Les propriétés retournées par référence ne peuvent pas avoir d’accesseurs définis
  • CS8341 : Les propriétés d'instance implémentées automatiquement dans les structs en lecture seule doivent être en lecture seule.
  • CS8657 : Le membre statique 'member' ne peut pas être marqué 'readonly'.
  • CS8658 : L’accesseur « set » implémenté automatiquement ne peut pas être marqué comme « readonly ».
  • CS8659 : La propriété implémentée automatiquement « propriété » ne peut pas être marquée comme « readonly » car elle dispose d’un accesseur « set ».
  • CS8660 : Il n’est pas possible de spécifier le modificateur « readonly » à la fois sur la propriété ou l’indexeur « property » et sur son accesseur. Supprimez l’un des deux.
  • CS8661 : Il n’est pas possible d’appliquer le modificateur « readonly » aux deux accesseurs de la propriété ou à l’indexeur « property ». Appliquez plutôt le modificateur « readonly » à la propriété elle-même.
  • CS8664 : « propriété » : « readonly » ne peut être utilisé sur des accesseurs que si la propriété ou l’indexeur dispose à la fois d’un accesseur get et d’un accesseur set
  • CS8852 : Une propriété ou un indexeur « property » de type « init-only » ne peut être affecté que dans un initialiseur d’objet, ou sur « this » ou « base » dans un constructeur d’instance ou un accesseur « init ».
  • CS8853 : « member » doit correspondre uniquement à l’initialisation du membre redéfini « member »
  • CS8855 : Les accesseurs « accessor » et « accessor » doivent tous deux être de type « init-only », ou aucun des deux
  • CS8856 : l’accesseur « init » n’est pas valide sur les membres statiques
  • CS8903 : Les accesseurs « accessor » et « accessor » doivent tous deux être de type « init-only », ou aucun des deux.
  • CS9029 : Les types et alias ne peuvent pas être nommés « obligatoires ».
  • CS9030 : « member » doit être déclaré obligatoire, car il effectue le remplacement du membre obligatoire « member »
  • CS9031 : Le membre requis 'member' ne peut pas être masqué par 'member'.
  • CS9032 : Le membre obligatoire ’’ ne peut pas être moins visible ou avoir un setter moins visible que le type conteneur ’’.
  • CS9033 : N’utilisez pas «System.Runtime.CompilerServices.RequiredMemberAttribute' . Utilisez plutôt le mot clé « required » sur les champs et propriétés obligatoires.
  • CS9034: Le membre obligatoire doit être définissable.
  • CS9035 : Le membre obligatoire doit être défini dans le constructeur d’initialiseur ou d’attribut d’objet.
  • CS9036 : Le membre obligatoire 'memberName' doit être affecté à une valeur, il ne peut pas utiliser un initialiseur de membre ou de collection imbriqué.
  • CS9037 : La liste des membres requis pour « type » est incorrecte et ne peut pas être interprétée.
  • CS9038 : La liste des membres requis pour le type de base 'type' est incorrecte et ne peut pas être interprétée. Pour utiliser ce constructeur, appliquez l’attribut 'SetsRequiredMembers .
  • CS9039 : ce constructeur doit ajouter «SetsRequiredMembers », car il est lié à un constructeur qui a cet attribut.
  • CS9040 : Le type ne peut pas satisfaire la contrainte «new() » sur le paramètre dans le type ou la méthode générique, car il a des membres requis.
  • CS9042: Le membre requis ne doit pas se voir attribuer la valeur « ObsoleteAttribute » sauf si le type qui le contient est obsolète ou si tous ses constructeurs sont obsolètes.
  • CS9045 : Les membres requis ne sont pas autorisés au niveau supérieur d’un script ou d’une soumission.
  • CS9258 : Dans cette version de langage, le mot clé «field » est lié à un champ de stockage synthétisé pour la propriété. Pour éviter de générer un champ de stockage synthétisé et de faire référence au membre existant, utilisez «this.field » ou «@field » à la place.
  • CS9263 : Une propriété partielle ne peut pas avoir d’initialiseur sur la définition et l’implémentation.

Les avertissements suivants peuvent être générés pour les propriétés associées à un champ de stockage :

  • CS9264 : la propriété « property » non nullable doit contenir une valeur non null lors de la sortie du constructeur. Envisagez d’ajouter le modificateur « obligatoire » ou de déclarer la propriété comme nullable, ou de gérer en toute sécurité le cas où «field » est null dans l’accesseur «get ».
  • CS9266: L’accesseur « accessor » de la propriété « property » devrait utiliser « field » car l’autre accesseur l’utilise.
  • CS9273 : Dans cette version de langage, 'field' est un mot clé dans un accesseur de propriété. Renommez la variable ou utilisez plutôt l’identificateur «@field ».

Les sections suivantes expliquent la cause et les correctifs pour ces erreurs et avertissements.

Accessibilité de l’accesseur

  • CS0273: Le modificateur d’accessibilité de l’accesseur ’property_accessor’ doit être plus restrictif que la propriété ou l’indexeur ’property’
  • CS0274 : Impossible de spécifier des modificateurs d’accessibilité pour les deux accesseurs de la propriété ou de l’indexeur 'property'
  • CS0275 : « accesseur » : les modificateurs d’accessibilité peuvent ne pas être utilisés sur les accesseurs d’une interface
  • CS0276 : 'property' : les modificateurs d’accessibilité sur les accesseurs peuvent uniquement être utilisés si la propriété ou l’indexeur a à la fois un accesseur get et un accesseur set
  • CS0442 : 'property' : les propriétés abstraites ne peuvent pas avoir d’accesseurs privés

Ces erreurs assurent le respect des règles applicables aux modificateurs d’accès des accesseurs de propriétés et d’indexeurs. Pour connaître les règles complètes, consultez Restriction de l'accessibilité des accesseurs et Accesseurs dans la spécification C#. Pour corriger ces erreurs, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Utilisez un modificateur d’accès plus restrictif que l’accessibilité déclarée de la propriété (CS0273). Par exemple, une propriété internal peut comporter un accesseur de définition private, mais non un accesseur de lecture public. L’accessibilité de l’accesseur doit constituer un sous-ensemble strict de l’accessibilité de la propriété.
  • Appliquez un modificateur d’accès à un seul des deux accesseurs (CS0274). La déclaration de propriété elle-même établit l’accessibilité par défaut pour les deux accesseurs, et un seul accesseur peut différer de cette valeur par défaut. Placez le modificateur d’accès sur quel accesseur a besoin d’un accès restreint.
  • Supprimez les modificateurs d’accès des accesseurs dans les déclarations de propriétés d’interface (CS0275). Les membres de l’interface définissent un contrat public et les modificateurs d’accès sur des accesseurs individuels ne sont pas autorisés. Si vous devez restreindre l’accès, appliquez la restriction dans la classe d’implémentation à la place.
  • Ajoutez à la fois un accesseur get et un accesseur set à la propriété avant d’appliquer un modificateur d’accès à l’un d’eux (CS0276). Les modificateurs d’accès sur les accesseurs distinguent la visibilité d’un accesseur de l’autre, ce qui nécessite que les deux accesseurs soient présents. Si la propriété n’a qu’un seul accesseur, supprimez le modificateur d’accès de celui-ci.
  • Modifiez le modificateur d'accès des accesseurs de propriétés abstraites de private à un modificateur moins restrictif (CS0442). Les membres abstraits doivent être accessibles aux classes dérivées afin que ces classes puissent fournir des implémentations. Utilisez protected, internalou protected internal au lieu de private.

Pour plus d’informations, consultez Restriction de l'accessibilité des accesseurs et Propriétés.

Syntaxe de déclaration de propriété

  • CS0547 : 'property' : propriété ou indexeur ne peut pas avoir de type void
  • CS0548 : ’property’ : la propriété ou l’indexeur doit posséder au moins un accesseur
  • CS0571 : 'function' : il est impossible d’appeler explicitement l’opérateur ou l’accesseur
  • CS0610 : Champ ou propriété ne peut pas être de type 'type'
  • CS0840 : « Nom de propriété » doit déclarer un corps, car il n’est pas marqué comme abstrait ou extern. Les propriétés implémentées automatiquement doivent définir les accesseurs get et set.
  • CS1014 : Accesseur get ou set attendu
  • CS1043 : { ou ; attendu

Ces erreurs veillent au respect des contraintes structurelles des déclarations de propriétés et d’indexeurs. Pour connaître les règles complètes, consultez Propriétés et la section Propriétés de la spécification C#. Pour corriger ces erreurs, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Remplacez le type de la propriété void par un type valide (CS0547). Les propriétés et les indexeurs représentent des expressions et void ne sont pas un type d’expression valide. Choisissez le type approprié pour les données que la propriété représente.
  • Ajoutez au moins un accesseur (getou setinit) à la déclaration de propriété (CS0548). Une propriété sans accesseurs n’a aucun moyen de lire ou d’écrire sa valeur. Incluez un get accesseur, un set ou init accesseur, ou les deux.
  • Accédez aux propriétés en utilisant la syntaxe de propriété, plutôt que d’appeler directement des méthodes d’accesseur (CS0571). Les accesseurs de propriété compilent sur des méthodes nommées get_PropertyName et set_PropertyName, mais appellent ces méthodes par le biais de la syntaxe de propriété (obj.Property et obj.Property = value). Le même principe s’applique aux opérateurs. Utilisez la syntaxe de l’opérateur (++obj) plutôt que d’appeler des méthodes comme op_Increment.
  • Remplacez le champ ou le type de propriété d’un type restreint par un type autorisé (CS0610). Certains types comme TypedReference et ArgIterator ne peuvent pas être utilisés en tant que champs ou propriétés. Ces types peuvent toujours être utilisés comme paramètres de méthode ou variables locales.
  • Pour une propriété en lecture seule, déclarez uniquement une propriété auto-implémentée get. Sinon, ajoutez simultanément les accesseurs get et set aux déclarations de propriétés implémentées automatiquement, ou fournissez des corps d’accesseurs explicites (CS0840). Pour une propriété nécessitant une logique personnalisée, utilisez le mot clé field, introduit dans C# 13, pour accéder au champ de stockage synthétisé par le compilateur dans votre bloc d’accesseur. Pour les propriétés abstract ou extern, supprimez les corps d’accesseurs puisque l’implémentation est fournie ailleurs. Pour les propriétés partial, fractionnez la déclaration et l’implémentation dans les déclarations de type partiel.
  • Vérifiez que le corps de la propriété contient uniquement des mots-clés d’accesseur valides—get, set ou init (CS1014). Les corps de propriété ne peuvent pas contenir d'instructions arbitraires ni de déclarations de membres. Déplacez les champs et les méthodes placés en dehors de la propriété dans le corps de la classe ou de la structure.
  • Utilisez une syntaxe d’accesseur de propriété appropriée avec des accolades ou des corps d’expression (CS1043). Les corps d’accesseurs doivent employer des accolades { }, les accesseurs à corps d’expression doivent utiliser la syntaxe =>, et les propriétés implémentées automatiquement doivent se terminer par un point-virgule après le jeton d’accesseur.

Pour plus d’informations, consultez Propriétés, Propriétés implémentées automatiquement et Utilisation des propriétés.

Remplacements de propriétés

  • CS0544 : 'property' : impossible de remplacer, car 'member' n’est pas une propriété
  • CS0545: ’function’ : substitution impossible, car ’property’ n’a pas d’accesseur get substituable
  • CS0546: ’accesseur’ : substitution impossible, car ’propriété’ n’a pas d’accesseur set substituable
  • CS1715 : 'type' : type doit être 'type' pour correspondre au membre substitué 'member'
  • CS8080: Les propriétés implémentées automatiquement doivent effectuer le remplacement de tous les accesseurs de la propriété redéfinie.

Ces erreurs appliquent les règles de substitution des propriétés dans les classes dérivées. Pour connaître l’ensemble des règles, consultez la section Héritage ainsi que les accesseurs virtuels, scellés, de remplacement et abstraits de la spécification C#. Pour corriger ces erreurs, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Vérifiez que le membre que vous remplacez est une propriété, et non un champ ou une méthode (CS0544). Le override mot clé d’une propriété ne peut cibler qu’un virtual, abstract ou override dans une classe de base. Pour masquer un membre non-propriété avec une propriété, utilisez le new mot clé au lieu de override.
  • Remplacez uniquement les accesseurs qui existent dans la déclaration de propriété de classe de base (CS0545, CS0546). Vous ne pouvez pas remplacer un accesseur de propriété qui n’est pas présent ou accessible dans la classe de base, car il n’existe aucune méthode virtuelle à remplacer. Si la propriété de la classe de base possède uniquement un accesseur get, vous ne pouvez pas ajouter un accesseur set au moyen d’un remplacement. Ajoutez l’accesseur manquant à la classe de base et marquez-le virtualou utilisez new pour masquer la propriété de classe de base avec une nouvelle définition de propriété.
  • Mettre en correspondance le type de la propriété substituée au type du membre substitué (CS1715). Les propriétés en lecture seule (get uniquement) prennent en charge les types de retour covariants à partir de C# 9, ce qui permet à la surcharge de retourner un type plus dérivé. Toutefois, les propriétés qui ont un set ou un init accesseur nécessitent une correspondance exacte de type, car le setter accepte les valeurs du type déclaré. Si vous avez besoin d’un autre type sur une propriété avec un setter, modifiez le type de propriété dans la classe dérivée pour qu’elle corresponde à la déclaration de classe de base, ou supprimez le setter et utilisez plutôt un type de retour covariant.
  • Incluez tous les accesseurs de la propriété de base lors d’un remplacement par une propriété implémentée automatiquement (CS8080). Les propriétés implémentées automatiquement génèrent des implémentations de stockage et d’accesseur. Elles doivent donc remplacer tous les accesseurs présents dans la classe de base. Si la propriété de base a à la fois get et set, alors la substitution implémentée automatiquement doit également avoir les deux. Pour remplacer uniquement certains accesseurs, implémentez la propriété avec des corps d’accesseurs explicites et un champ de stockage explicite plutôt qu’au moyen d’une implémentation automatique.

Pour plus d’informations, consultez Héritage, Propriétés et Utilisation des propriétés.

Propriétés reposant sur un champ de stockage

  • CS9258 : Dans cette version de langage, le mot clé «field » est lié à un champ de stockage synthétisé pour la propriété. Pour éviter de générer un champ de stockage synthétisé et de faire référence au membre existant, utilisez «this.field » ou «@field » à la place.
  • CS9263 : Une propriété partielle ne peut pas avoir d’initialiseur sur la définition et l’implémentation.
  • CS9264 : la propriété « property » non nullable doit contenir une valeur non nulle lors de la sortie du constructeur. Envisagez d’ajouter le modificateur 'required' ou de déclarer la propriété comme nullable, ou de gérer en toute sécurité le cas où «field» est null dans l’accesseur «get».
  • CS9266: L’accesseur « accessor » de la propriété « property » devrait utiliser « field » car l’autre accesseur l’utilise.
  • CS9273 : Dans cette version de langage, 'field' est un mot clé dans un accesseur de propriété. Renommez la variable ou utilisez plutôt l’identificateur «@field ».

Pour corriger les erreurs de propriété basées sur des champs, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Renommez une variable nommée field en un autre identificateur ou utilisez la @field syntaxe d’échappement pour faire référence à votre variable (CS9258, CS9273). Cette correction est nécessaire, car field il s’agit d’un mot clé contextuel dans les accesseurs de propriétés en C# 13 et versions ultérieures, où il fait référence au champ de stockage synthétisé par le compilateur. Si vous souhaitez accéder à un membre existant nommé field au lieu du champ de stockage synthétisé, qualifiez-le avec this.field pour lever l’ambiguïté de la référence.
  • Supprimez l’initialiseur de la définition de propriété partielle ou de l’implémentation, en conservant une seule (CS9263). Cette correction est requise, car l'autorisation des initialiseurs dans les deux emplacements créerait une ambiguïté quant à la valeur à utiliser et pourrait entraîner l’initialisation du champ de stockage deux fois avec des valeurs potentiellement différentes.
  • Ajoutez les [field: MaybeNull, AllowNull] attributs à la déclaration de propriété pour indiquer que le champ de stockage doit être traité comme nullable (CS9264). Cette correction aligne les attentes en matière de nullabilité entre le type de propriété et le champ de stockage synthétisé par le compilateur, en résolvant l’incompatibilité où la propriété est déclarée non nullable, mais l’utilisation field du mot clé suggère qu’elle pourrait être null. Vous pouvez également remplacer le type de propriété par Nullable, ajouter le required modificateur pour garantir l’initialisation ou initialiser la propriété dans le constructeur.
  • Utilisez systématiquement soit le mot-clé field dans les deux accesseurs, soit un champ de stockage explicite dans les deux accesseurs (CS9266). Cette correction empêche les bogues potentiels dans lesquels un accesseur modifie le champ de stockage synthétisé par le compilateur tandis que l’autre accesseur modifie un autre emplacement de stockage, ce qui entraîne un comportement de propriété incohérent.

Pour plus d’informations, consultez le mot clé de champ et les propriétés partielles.

Propriétés en lecture seule

  • CS0200: Il n’est pas possible d’affecter une valeur à la propriété ou la « propriété » d’indexeur car celle-ci est en lecture seule
  • CS8341 : Les propriétés d’instance implémentées automatiquement dans les structs en lecture seule doivent être en lecture seule.
  • CS8657: Le membre statique « member » ne peut pas être marqué comme « readonly ».
  • CS8658 : L’accesseur « set » implémenté automatiquement ne peut pas être marqué comme « readonly ».
  • CS8659: La propriété implémentée automatiquement « propriété » ne peut pas être marquée comme « readonly » car elle dispose d’un accesseur « set ».
  • CS8660: Il n’est pas possible de spécifier le modificateur « readonly » à la fois sur la propriété ou l’indexeur « property » et sur son accesseur. Supprimez l’un des deux.
  • CS8661: Il n’est pas possible d’appliquer le modificateur « readonly » aux deux accesseurs de la propriété ou à l’indexeur « property ». Appliquez plutôt le modificateur « readonly » à la propriété elle-même.
  • CS8664 :« propriété » : « readonly » ne peut être utilisé sur des accesseurs que si la propriété ou l’indexeur dispose à la fois d’un accesseur get et d’un accesseur set

Pour corriger les erreurs de propriété en lecture seule, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Ajoutez un accesseur set ou init à la propriété pour la rendre modifiable (CS0200). Cette correction est nécessaire, car les propriétés sans accesseurs définis sont en lecture seule et peuvent uniquement être affectées dans le constructeur ou l’initialiseur de champ du type déclarant. Si vous avez besoin que la propriété soit définie lors de l’initialisation de l’objet mais immuable par la suite, utilisez un init accesseur au lieu d’un set accesseur. Si la propriété doit demeurer en lecture seule, déplacez l’affectation dans le constructeur où l’initialisation est autorisée, ou réévaluez la nécessité réelle de cette affectation.
  • Marquez les propriétés d’instance implémentées automatiquement comme readonly lorsque vous les déclarez dans un readonly struct (CS8341). Cette correction applique le contrat d'immuabilité de la structure conteneur, garantissant que tous les membres de l'instance respectent la garantie readonly. Si la propriété doit être mutable, supprimez le modificateur readonly de la déclaration de structure ou implémentez la propriété avec un champ de stockage explicite et des corps d’accesseur qui ne modifient pas l’état de l’instance.
  • Retirez le readonly modificateur dans les déclarations de propriété statique ou d’accesseur (CS8657). Cette correction est requise, car le readonly modificateur s’applique uniquement aux membres d’instance des structs pour indiquer qu’ils ne modifient pas l’état de l’instance et que les membres statiques n’ont pas d’état d’instance à protéger. Si vous avez besoin d’une propriété statique en lecture seule, omettez simplement l’accesseur set plutôt que d’utiliser le readonly modificateur.
  • Supprimez le modificateur readonly des accesseurs set implémentés automatiquement, ou appliquez-le uniquement à l’accesseur get (CS8658). Cette correction est nécessaire, car set les accesseurs modifient intrinsèquement l’état, ce qui contredit l’objectif du modificateur qui garantit aucune modification de l’état de readonly l’instance. Si vous avez besoin d’une propriété qui peut être définie pendant l’initialisation, mais qu’elle est en lecture seule par la suite, utilisez un init accesseur au lieu d’un set accesseur.
  • Supprimez le readonly modificateur de la déclaration de propriété lorsque la propriété a un set accesseur (CS8659). Cette correction est requise, car les propriétés avec set des accesseurs peuvent modifier l’état de l’instance, ce qui enfreint la readonly garantie. Si vous avez besoin de configurer uniquement lors de l'initialisation, remplacez l'accesseur set par un autre init, ou supprimez entièrement l'accesseur set afin que la propriété soit vraiment en lecture seule.
  • Placez le readonly modificateur sur la déclaration de propriété ou sur des accesseurs individuels, mais pas les deux (CS8660, CS8661). Cette correction empêche les déclarations de modificateur redondantes susceptibles de créer une confusion quant aux modificateurs qui sont prioritaires. Si vous souhaitez désigner des accesseurs spécifiques avec readonly, retirez le modificateur de la déclaration de la propriété et placez-le uniquement sur les accesseurs. Sinon, si tous les accesseurs doivent être readonly, appliquez ce modificateur à la propriété elle-même plutôt qu’aux accesseurs individuels.
  • Assurez-vous que les accesseurs get et set sont présents lors du marquage des accesseurs individuels en tant que readonly (CS8664). Cette correction est nécessaire, car le readonly modificateur sur les accesseurs individuels fait la distinction entre les accesseurs qui modifient l’état et ceux qui ne le font pas, ce qui n’est logique que lorsque les deux types d’accesseur existent. Si la propriété n’a qu’un get accesseur, marquez l'intégralité de la propriété comme readonly au lieu de l’accesseur individuel.

Pour plus d’informations, consultez les membres de l’instance en lecture seule, le mot-clé ‹init› et les propriétés.

Propriétés init-only

  • CS8852: Une propriété ou un indexeur « property » de type « init-only » ne peut être affecté que dans un initialiseur d’objet, ou sur « this » ou « base » dans un constructeur d’instance ou un accesseur « init ».
  • CS8853: « member » doit correspondre uniquement à l’initialisation du membre redéfini « member »
  • CS8855: Les accesseurs « accessor » et « accessor » doivent tous deux être de type « init-only », ou aucun des deux
  • CS8856 : l’accesseur « init » n’est pas valide sur les membres statiques
  • CS8903: Les accesseurs « accessor » et « accessor » doivent tous deux être de type « init-only », ou aucun des deux.

Ces erreurs imposent les règles de l’accesseur init, permettant ainsi une initialisation d’un objet immuable. Pour connaître les règles complètes, consultez le mot clé init. Pour corriger ces erreurs, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Déplacez les affectations des propriétés en lecture seule vers un initialiseur d’objet, un constructeur ou un accesseur init (CS8852). Les propriétés en lecture seule ne peuvent plus recevoir d’affectation une fois la construction de l’objet terminée. Affectez la valeur dans le corps du constructeur, un accesseur init ou une expression d’initialiseur d’objet (new MyType { Property = value }). Si vous devez affecter la propriété après la construction, remplacez l'accesseur init par un accesseur set.
  • Faites correspondre le type d’accesseur init ou set lors du remplacement d’une propriété (CS8853). Si la propriété de classe de base utilise un init accesseur, la propriété de substitution doit également utiliser init. De même, si la base utilise set, la substitution doit utiliser set. Cette cohérence garantit que le contrat d’immuabilité établi par le type de base est conservé dans les types dérivés.
  • Utilisez le même type d’accesseur (init ou set) sur les deux accesseurs dans une implémentation d’interface explicite (CS8855). Lorsqu’un type implémente explicitement deux interfaces qui déclarent la même propriété, les deux implémentations d’accesseur doivent être cohérentes : soit elles utilisent toutes deux init, soit elles utilisent toutes deux set.
  • Supprimez l’accesseur init des déclarations de propriétés statiques, ou remplacez-le par un accesseur set (CS8856). L’accesseur init est conçu pour les modèles d’initialisation d’instance liés à la construction d’objets, et les membres statiques ne participent pas à l’initialisation d’objet. Utilisez un set accesseur pour les propriétés statiques mutables ou supprimez entièrement le setter pour les propriétés statiques en lecture seule.
  • Retirez le readonly modificateur de l’accesseur init (CS8903). Le modificateur readonly appliqué à un membre de structure garantit que ce membre ne modifie pas l’instance de la structure. Étant donné qu’un accesseur affecte l’état de l’instance init, il modifie intrinsèquement la structure et ne peut pas être marqué readonly. Pour rendre l’accesseur getreadonly, appliquez le modificateur de readonly uniquement à l’accesseur get.

Pour plus d’informations, consultez le mot clé init et les initialiseurs d'objet et de collection.

Initialiseurs de propriétés

  • CS8050 : Seules les propriétés implémentées automatiquement, ou les propriétés qui utilisent le mot clé « field », peuvent avoir des initialiseurs.
  • CS8051 : Les propriétés implémentées automatiquement doivent avoir des accesseurs get.
  • CS8053 : Les propriétés d’instance dans les interfaces ne peuvent pas avoir d’initialiseurs.

Pour corriger les erreurs d’initialisation de propriété, appliquez l’une des modifications suivantes selon le diagnostic concerné :

  • Transformez la propriété afin qu’elle utilise la syntaxe d’implémentation automatique en supprimant les corps des accesseurs et en laissant le compilateur générer le champ de stockage (CS8050). Cette correction est nécessaire, car seules les propriétés avec le stockage géré par le compilateur peuvent avoir des initialiseurs, ce qui garantit que l’initialisation se produit avant l’exécution d’une logique d’accesseur. Vous pouvez également modifier les implémentations des accesseurs afin d’utiliser le mot-clé field pour accéder au champ de stockage synthétisé par le compilateur. Cette approche active l'initialiseur tout en conservant la logique personnalisée des accesseurs. Si aucune approche n’est appropriée, supprimez l’initialiseur et affectez la valeur dans un constructeur à la place, où vous avez un contrôle total sur la séquence d’initialisation.
  • Ajoutez un get accesseur à la propriété implémentée automatiquement pour permettre la lecture de la valeur initialisée (CS8051). Cette correction est requise, car les initialiseurs définissent une valeur qui doit être récupérable, et une propriété en écriture seule enfreint cette attente fondamentale d’initialisation des propriétés. Si vous avez vraiment besoin d'une propriété à écriture seule, implémentez explicitement les accesseurs avec un champ de stockage et définissez le champ directement dans un constructeur plutôt que d'utiliser un initialiseur de propriété.
  • Supprimez l’initialiseur des déclarations de propriétés d’interface (CS8053). Cette correction est nécessaire, car les interfaces définissent des contrats pour l’implémentation de types plutôt que de fournir des implémentations concrètes avec des valeurs initiales. Si vous devez fournir des valeurs par défaut, implémentez la propriété dans une classe qui implémente l’interface ou utilisez les méthodes d’interface par défaut (disponibles en C# 8.0 et versions ultérieures) pour fournir une implémentation par défaut.

Pour plus d’informations, consultez Propriétés, Propriétés implémentées automatiquement et mot clé de champ.

Membres nécessaires

  • CS9029 : Les types et alias ne peuvent pas être nommés « obligatoires ».
  • CS9030: « member » doit être déclaré obligatoire, car il effectue le remplacement du membre obligatoire « member »
  • CS9031: Le membre obligatoire « member » ne peut pas être masqué par « member ».
  • CS9032 : Un membre requis ne peut pas être moins visible ni avoir un setter moins visible que le type conteneur.
  • CS9033 : N’utilisez pas «System.Runtime.CompilerServices.RequiredMemberAttribute' . Utilisez plutôt le mot clé « required » sur les champs et propriétés obligatoires.
  • CS9034: Le membre obligatoire doit être définissable.
  • CS9035 : Le membre obligatoire doit être défini dans le constructeur d’initialiseur ou d’attribut d’objet.
  • CS9036 : Le membre obligatoire 'memberName' doit être affecté à une valeur, il ne peut pas utiliser un initialiseur de membre ou de collection imbriqué.
  • CS9037 : La liste des membres requis pour « type » est incorrecte et ne peut pas être interprétée.
  • CS9038 : La liste des membres requis pour le type de base 'type' est incorrecte et ne peut pas être interprétée. Pour utiliser ce constructeur, appliquez l’attribut 'SetsRequiredMembers .
  • CS9039 : ce constructeur doit ajouter «SetsRequiredMembers », car il est lié à un constructeur qui a cet attribut.
  • CS9040 : Le type ne peut pas satisfaire la contrainte «new() » sur le paramètre dans le type ou la méthode générique, car il a des membres requis.
  • CS9042 : Le membre obligatoire ne doit pas être attribué avec «ObsoleteAttribute », sauf si le type conteneur est obsolète ou que tous les constructeurs sont obsolètes.
  • CS9045 : Les membres requis ne sont pas autorisés au niveau supérieur d’un script ou d’une soumission.

Pour corriger les erreurs liées aux membres obligatoires, appliquez l’une des modifications suivantes selon le diagnostic concerné :

  • Évitez d’utiliser required comme type ou nom d’alias (CS9029). Cette correction est nécessaire, car required il s’agit d’un mot clé contextuel en C# 11 et ultérieur, et son utilisation en tant que nom de type crée une ambiguïté dans le code où le mot clé peut apparaître.
  • Assurez-vous que les membres dérivés conservent le modificateur required lors de la redéfinition des membres requis (CS9030). Cette correction applique le contrat établi par la classe de base, garantissant que tous les types dérivés conservent les mêmes exigences d’initialisation. Évitez de masquer les membres requis avec des membres non requis dans les classes dérivées (CS9031), car cette action interrompt le contrat d’initialisation attendu par les consommateurs du type de base.
  • Rendez les membres obligatoires au moins aussi visibles que leur type conteneur, et assurez-vous également que les setters de propriété disposent d’une visibilité suffisante (CS9032). Cette correction empêche les situations où un type est accessible publiquement, mais ses membres requis ne peuvent pas être initialisés à partir de tous les contextes où le type est construit.
  • Utilisez le required mot clé au lieu d’appliquer RequiredMemberAttribute manuellement (CS9033). Cette correction garantit que le compilateur génère les métadonnées correctes et applique toutes les règles de membre requises, que l’application d’attribut manuel risque de ne pas faire correctement.
  • Assurez-vous que les membres obligatoires possèdent des accesseurs de définition ou qu’ils puissent autrement recevoir une définition (CS9034). Cette correction est nécessaire, car les membres requis doivent être initialisés lors de la création d’objets, ce qui nécessite un accès en écriture. Lors de la création d’instances, initialisez les membres requis directement dans les initialiseurs d’objet (CS9035, CS9036). Vous devez affecter une valeur à chaque membre requis au lieu d’utiliser des initialiseurs de membres imbriqués ou des initialiseurs de collection, car le membre requis lui-même doit être défini avant d’accéder à ses propriétés.
  • Appliquez l’attribut SetsRequiredMembers aux constructeurs qui initialisent tous les membres requis dans leur corps (CS9038, CS9039). Cette correction informe le compilateur que le constructeur remplit le contrat membre requis, ce qui autorise la création d’objets sans initialiseurs d’objet. Si un constructeur est lié à un autre constructeur avec SetsRequiredMembers, il doit également avoir l’attribut.
  • Évitez d’utiliser les membres requis dans les types qui doivent satisfaire la new() contrainte (CS9040), car le constructeur sans paramètre ne peut pas garantir l’initialisation de membre requise sans initialiseur d’objet. Ne marquez pas les membres requis comme obsolètes, sauf si le type conteneur ou tous les constructeurs sont obsolètes (CS9042), pour empêcher les situations où les membres sont requis, mais leur utilisation est déconseillée. Les membres obligatoires ne sont pas autorisés dans les instructions de niveau supérieur ou les contextes de script (CS9045), car ces contextes ne prennent pas en charge la syntaxe d’initialisation d’objet nécessaire pour définir les membres requis.

Pour plus d’informations, consultez l’article de référence sur les modificateurs requis et le guide des initialiseurs d’objets et de collection .

Propriétés retournant des références

  • CS8145 : Les propriétés implémentées automatiquement ne peuvent pas retourner par référence
  • CS8147 : Les propriétés retournées par référence ne peuvent pas avoir d’accesseurs définis

Pour corriger les erreurs de propriété de retour de référence, appliquez l’une des modifications suivantes en fonction du diagnostic spécifique :

  • Implémentez explicitement la propriété avec un champ de stockage et utilisez le mot-clé ref dans l’expression de retour de l’accesseur get (CS8145). Cette correction est nécessaire, car les propriétés implémentées automatiquement génèrent un champ de stockage privé que le compilateur gère en interne. Le renvoi d’une référence à un champ privé expose le stockage interne auquel les appelants ne doivent pas accéder directement. Pour créer une propriété retournant une référence, déclarez un champ de type explicite et retournez-le avec la syntaxe => ref backingField. Sinon, si vous n'avez pas besoin de retourner une référence permettant la modification directe du stockage concerné, supprimez l'attribut ref de la déclaration de propriété.
  • Supprimez l’accesseur set des propriétés de retour de référence (CS8147). Cette correction est requise, car une propriété de retour de référence fournit déjà un accès en lecture et en écriture via la référence retournée elle-même. Les appelants peuvent modifier directement la valeur via la référence sans avoir besoin d’une méthode setter distincte. L’inclusion d’un set accesseur créerait deux mécanismes différents pour modifier le même stockage, ce qui est redondant et pourrait entraîner une confusion quant au chemin de modification à utiliser.

Pour plus d’informations, consultez les sections Retours ref et Locales ref ainsi que Propriétés