Je lisais de nouvelles fonctionnalités variables en C # 7 ici . J'ai deux questions:
Ça dit
Nous autorisons également les "rejets" comme paramètres de sortie, sous la forme d'un
_
, pour vous permettre d’ignorer les paramètres qui vous intéressent:p.GetCoordinates(out var x, out _); // I only care about x
Q: Je suppose que c'est simplement une info et non une nouvelle fonctionnalité de C # 7 car nous pouvons le faire dans les versions antérieures à 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 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?
Discards , dans C # 7, peut être utilisé partout où une variable est déclarée, pour - comme son nom le suggère - pour ignorer le résultat. Donc, un rejet peut être utilisé avec les variables out:
p.GetCoordinates(out var x, out _);
et il peut être utilisé pour ignorer un résultat d'expression:
_ = 42;
Dans l'exemple,
p.GetCoordinates(out var x, out _);
_ = 42;
Il n'y a pas de variable, _
, en cours d'introduction. Il n'y a que deux cas d'utilisation d'un rejet.
Si toutefois, un identifiant _
existe dans la portée, les rejets ne peuvent pas être utilisés:
var _ = 42;
_ = "hello"; // error - a string cannot explicitly convert from string to int
L'exception à ceci est quand un _
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 _
puis il est traité comme une référence à une variable existante, _
, si c'est dans la portée, par exemple:
string _;
int.TryParse("1", out _); // complains _ is of the wrong type
Finalement, le *
La notation a été proposée au début des discussions sur les rejets, mais a été abandonnée au profit de _
, cette dernière étant une notation plus couramment utilisée dans d’autres langues .
Un autre exemple de l'opérateur de rejet _
en C # 7 est correspondance de modèle une variable de type object
dans une instruction switch
récemment ajoutée en C # 7:
Code:
static void Main(string[] args)
{
object x = 6.4;
switch (x)
{
case string _:
Console.WriteLine("it is string");
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 à la case ... _
.
Considérez l'extrait suivant
static void Main(string[] 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 en coulisse, les deux appels font la même chose.
Comme @ Servé Laurijssen l'a souligné, la chose intéressante est que vous n'avez pas à pré-déclarer variables, ce qui est pratique si vous n'êtes pas intéressé par certaines valeurs.
Concernant la première question
Je suppose que ceci est juste une info et pas une nouvelle fonctionnalité de C # 7 car nous pouvons le faire dans les versions antérieures à C # 7.0.
var _; if (Int.TryParse(str, out _)) // ...
La nouveauté est que vous n'avez pas à déclarer _
plus à l'intérieur ou à l'extérieur de l'expression et vous pouvez simplement taper
int.TryParse(s, out _);
Essayez de faire cette ligne avant C # 7:
private void btnDialogOk_Click_1(object sender, RoutedEventArgs e)
{
DialogResult = int.TryParse(Answer, out _);
}