Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

C# : initialisation d’instance, une syntaxe méconnue

[new:20/01/2013]C# est d’une telle finesse qu’on oublie parfois de les utiliser, habituer à écrire les choses d’une certaine façon. Les initialisations d’instance par exemple disposent d’une syntaxe si ce n’est méconnue en tout cas fort peu utilisée et qui, pourtant, est bien pratique. Une ruse à connaitre…

Initialisation d’instance

C’est très simple, plutôt que d’écrire :

var b = new Button();
b.Content = "Ok";
b.Visibility=Visibility.Collapsed

 

Il est plus facile d’écrire :

var b = new Button { Content = "Ok", Visibility=Visibility.Collapsed };

 

Rien de sorcier, c’est pratique, plus lisible, bref cela n’a que des avantages.

Une limite à faire sauter

Même si cela est très pratique, là où cela se corse c’est lorsque l’objet créé en contient d’autres.

Prenons un cas concret : une ChildWindow sous Silverlight qui possède donc deux boutons, CancelButton et OkButton, plus, généralement, un TextBlock que nous appellerons TxtMessage.

Si je veux utiliser la même syntaxe réduite pour initialiser une nouvelle instance de ChildWindow je vais me retrouver “coincé" lorsque je vais vouloir adresser le texte du TextBlock.

En effet, écrire :

var dialog = new MyChildWindow { TxtMessage.Text = "Coucou!" }

 

ça ne passe pas…

Je ne peux pas déférencer la propriété Text à l’intérieur de la propriété TxtMessage de la ChildWindow.

Coincé ?

C’est ce qu’on pense généralement, du coup on extrait de la séquence d’initialisation qui ne passe pas et on se retrouve avec un code spaghetti, une partie des propriétés initialisées avec la syntaxe réduite, et en dessous le reste, initialisé “normalement” (du genre “dialog.TxtMessage.Text=”Coucou!””).

La feinte à connaitre

C# nous révèle souvent des surprises quand on prend le temps de lire la documentation de sa syntaxe… Mais on oublie souvent de tout lire, pensant déjà connaitre le principal.

justement, c’est dans le détail que les choses se jouent…

Voici donc comment écrire en syntaxe courte l’initialisation donnée en exemple plus haut :

var dialog = new MyChildWindow { TxtMessage = { Text = "Coucou!"}  };

 

Etonnant non ? Affecter le résultat d’une opération est un truc connu (var a = (b = 2x3); donnera à “a” la valeur du résultat tout en l’affectant déjà à “b”). Mais ici c’est quelque chose d’autre…

Vous noterez qu’après le signe égal un niveau d’accolades américaines supplémentaire est ouvert. Ce qui est affecté à TxtMessage n’est donc pas le résultat de l’affectation “Text=”Coucou!”” car cela planterait (on ne peut pas affecter une String à un TextBlock les types ne sont pas compatibles).

Cette syntaxe permet en réalité d’ouvrir une “sous affectation” sur la propriété indiquée (ici on créé on ouverture sur les propriété de TxtMessage qui est lui même une propriété de la child Window).

Le résultat est celui escompté, à la sortie de l’initialisation le TextBlock portant le nom TxtMessage placé à l’intérieur de MyChildWindow aura bien son texte initialisé à “Coucou!”.

Fantastique C# non ?

Moi il me fascine toujours Sourire

Une Preuve

Le plus simple pour tester des petits trucs comme cela c’est d’utiliser LinqPad, un outil indispensable.

Ainsi, voici un exemple tapé et visualisé sous LinqPad qui illustre l’utilisation de cette syntaxe spéciale et son résultat :

image

Conclusion

Je ne sais pas combien d’entre vous connaissaient déjà cette syntaxe et l’avaient utilisée.

Personnellement j’avoue bien humblement que si Resharper ne me l’avait pas proposée je ne saurai toujours pas que c’est possible, et pourtant j’ai été MVP C# (honte sur moi !).

Alors suis-je une truffe ignare (parfois on se sent bête de ne pas savoir un truc que tout le monde va dire “ah oui, classique, je m’en sers tous les jours”, genre moment de solitude !) ou bien est-ce une ruse qui justifie pleinement d’avoir lu ce billet ?

Répondez franchement Sourire

Faites des heureux, PARTAGEZ l'article !