Dans WinForms, il est courant qu'une fonction d'initialisation courante initialise des variables de référence (par exemple)
class SomeClass : Form { Button b; SomeClass() { InitializeComponents(); } SomeClass(Container x) { InitializeComponents(); } void InitializeComponents() { b = new Button(); } }
Comme vous pouvez le voir, b est toujours initialisé à une valeur non nulle. Cependant, C # 8 se plaindra toujours que SomeClass () n'initialise pas la valeur non nullable b.
Bien sûr, je pourrais marquer b comme nullable (Button? B) cependant, maintenant j'obtiendrai un avertissement sur chaque utilisation de b, car la nullité n'est pas vérifiée (elle ne peut pas être nulle ...)
Quelle est la meilleure façon de résoudre ce problème. Existe-t-il un attribut qui peut être utilisé pour marquer InitializeComponent comme étant toujours appelé par le constructeur?
Veuillez noter qu'il s'agit d'un modèle très courant dans WinForms (chaque composant ...)
Yuval
3 Réponses :
Selon les documents de prévisualisation < / a>:
Q: Pourquoi des avertissements sont-ils signalés pour les champs initialisés indirectement par le constructeur, ou en dehors du constructeur?
R: Le compilateur reconnaît les champs affectés explicitement dans le constructeur uniquement, et avertit pour les autres champs déclarés comme non nullables. Cela ne tient pas compte des autres façons dont les champs peuvent être initialisés, comme l'usine méthodes, méthodes d'assistance, définisseurs de propriétés et initialiseurs d'objets. nous étudiera la reconnaissance des modèles d'initialisation courants avertissements inutiles.
Donc, il n'y a aucun moyen, pour le moment , d'obtenir ce que vous voulez sans déplacer cette affectation directement dans le constructeur (ou l'assigner sur la ligne qui la déclare).
Depuis que vous avez répondu à cela, certains attributs ont été ajoutés comme [MaybeNull]
. Savez-vous si un élément a été ajouté indiquant au compilateur que le champ est toujours initialisé?
Je ne suis pas au courant d'une telle chose @ andre_ss6.
Pour votre exemple très spécifique, la solution est de fusionner InitializeComponent ()
dans le constructeur par défaut et de l'invoquer à partir du second.
class SomeClass : Form { private readonly Button b; public SomeClass() { b = new Button(); } public SomeClass(Container x): this() { // Something else... } }
Malheureusement, il s'agit d'une limitation actuelle bien connue et, de plus, tout le code généré par le concepteur ne suivra pas ce modèle, vous devrez peut-être mettre un #nullable disable code> (ou l'une des autres directives, selon le cas) ici et là.
rendre le champ privé: private System.Windows.Forms.Button button1;
OP a dit que la valeur n'est jamais nulle. (Et le fait de le marquer comme Nullable entraînera plus d'erreurs sur la ligne.) Ce champ ne doit pas être marqué comme Nullable.