Je lisais ici les nouvelles fonctionnalités variables de C # 7. J’ai deux questions:
Ça dit
Nous autorisons également les parameters “rejetés”, sous la forme d’un
_
, pour vous permettre d’ignorer les parameters qui ne vous intéressent pas:p.GetCoordinates(out var x, out _); // I only care about x
Q: Je suppose que c’est juste une info et non une nouvelle fonctionnalité de C # 7 parce que nous pouvons le faire aussi dans pre C # 7.0:
var _; if (Int.TryParse(str, out _)) ...
ou est-ce que je manque quelque chose ici?
Mon code donne une erreur quand je le fais comme mentionné dans le même blog:
~Person() => names.TryRemove(id, out *);
*
n’est pas un identifiant valide. Un oubli de Mads Torgersen, je suppose?
Les rejets, en C # 7, peuvent être utilisés partout où une variable est déclarée, pour supprimer – comme son nom l’indique – le résultat. Donc, il peut être utilisé avec des variables:
p.GetCoordinates(out var x, out _);
et il peut être utilisé pour écarter un résultat d’expression:
_ = 42;
Dans l’exemple,
p.GetCoordinates(out var x, out _); _ = 42;
Il n’y a pas de variable _
introduite. Il n’y a que deux cas de rejet utilisés.
Si toutefois, un identifiant _
existe dans la scope, alors les rejets ne peuvent pas être utilisés:
var _ = 42; _ = "hello"; // error - a ssortingng cannot explicitly convert from ssortingng to int
L’exception à cela est quand une variable _
est utilisée comme variable de sortie. Dans ce cas, le compilateur ignore le type ou var
et le traite comme une suppression:
if (p.GetCoordinates(out double x, out double _)) { _ = "hello"; // works fine. Console.WriteLine(_); // error: _ doesn't exist in this context. }
Notez que cela ne se produit que si, dans ce cas, out var _
ou out double _
est utilisé. Il suffit d’utiliser out _
et il est traité comme une référence à une variable existante, _
si elle est dans la scope, par exemple:
ssortingng _; int.TryParse("1", out _); // complains _ is of the wrong type
Enfin, la notation *
été proposée tôt dans les discussions sur les rejets, mais a été abandonnée au profit de _
car cette dernière est une notation plus couramment utilisée dans d’autres langues .
Considérez l’extrait suivant
static void Main(ssortingng[] args) { //.... int a; int b; Test(out a, out b); Test(out _, out _); //.... } private static void Test(out int a, out int b) { //... }
C’est ce qui se passe:
... 13: int a; 14: int b; 15: 16: Test(out a, out b); 02340473 lea ecx,[ebp-40h] 02340476 lea edx,[ebp-44h] 02340479 call 02340040 0234047E nop 17: Test(out _, out _); 0234047F lea ecx,[ebp-48h] 02340482 lea edx,[ebp-4Ch] 02340485 call 02340040 0234048A nop ...
Comme vous pouvez le voir derrière la scène, les deux appels font la même chose.
Comme @ Servé Laurijssen l’a souligné, ce qui est cool, c’est que vous n’avez pas à pré-déclarer de variables, ce qui est pratique si vous n’êtes pas intéressé par certaines valeurs.
Un autre exemple de l’opérateur Discard _
dans C # 7 est de mettre en correspondance une variable de type object
dans une instruction switch
, qui a été récemment ajoutée dans C # 7:
Code:
static void Main(ssortingng[] args) { object x = 6.4; switch (x) { case ssortingng _: Console.WriteLine("it is ssortingng"); break; case double _: Console.WriteLine("it is double"); break; case int _: Console.WriteLine("it is int"); break; default: Console.WriteLine("it is Unknown type"); break; } // end of main method }
Ce code correspond au type et ignore la variable transmise au case ... _
.
En ce qui concerne la première question
Je suppose que c’est juste une info et non une nouvelle fonctionnalité de C # 7 car nous pouvons le faire aussi dans le pré-C # 7.0.
var _; if (Int.TryParse(str, out _)) // ...
La nouveauté est que vous n’avez plus à déclarer _
intérieur ou à l’extérieur de l’expression et vous pouvez simplement taper
int.TryParse(s, out _);
Essayez de faire ce liner pre C # 7:
private void btnDialogOk_Click_1(object sender, RoutedEventArgs e) { DialogResult = int.TryParse(Answer, out _); }