82 votes

C # 7: trait de soulignement (_) & étoile (*) dans la variable Out

J'ai lu sur les nouvelles caractéristiques variables en C#7 ici. J'ai deux questions:

  1. Il dit

    Nous permettre de "rejets" que les paramètres de sortie, sous la forme d'un _, pour vous permettre d'ignorer les paramètres de sortie, vous n'avez pas de soins sur:

    p.GetCoordinates(out var x, out _); // I only care about x
    

    Q: je suppose que c'est juste une info et pas une nouvelle fonctionnalité de C#7, parce que nous pouvons le faire dans le pré C#7.0:

    var _;
    if (Int.TryParse(str, out _))
    ...
    

    ou ai-je raté quelque chose ici?

  2. Mon code donne une erreur quand je fais comme mentionné dans le même blog:

    ~Person() => names.TryRemove(id, out *);
    

    * n'est pas un identificateur valide. Une surveillance par Mads Torgersen, je suppose?

116voto

David Arno Points 15499

Les rejets, en C#7 peut être utilisé partout où une variable est déclarée, comme le nom le suggère, de jeter le résultat. Ainsi, un écart peut être utilisé avec les variables:

p.GetCoordinates(out var x, out _);

et il peut être utilisé pour jeter un résultat de l'expression:

_ = 42;

Dans l'exemple,

p.GetCoordinates(out var x, out _);
_ = 42;

Il n'y a pas de variable, _, être présenté. Il y a seulement deux cas d'un écart utilisé.

Cependant, si un identificateur _ existe dans le champ d'application, puis les rejets ne peuvent pas être utilisés:

var _ = 42;
_ = "hello"; // error - a string cannot explicitly convert from string to int

L'exception à cette règle est lorsque l' _ variable est utilisée comme une variable. Dans ce cas, le compilateur ignore le type ou var et la traite comme un rebut:

if (p.GetCoordinates(out double x, out double _))
{
    _ = "hello"; // works fine.
    Console.WriteLine(_); // error: _ doesn't exist in this context.
}

Notez que cela se produit uniquement si, dans ce cas, out var _ ou out double _ est utilisé. Suffit d'utiliser out _ , puis il est traité comme une référence à une variable existante, _, si elle est dans le champ d'application, par exemple:

string _;
int.TryParse("1", out _); // complains _ is of the wrong type

Enfin, l' * de la notation a été proposé dès le début des discussions autour de rejets, mais a été abandonné en faveur de l' _ en raison de la plus couramment utilisée de la notation dans d'autres langues.

31voto

Cyber Progs Points 1932

Un autre exemple d'opérateur de rejet _ en C # 7 consiste à faire correspondre 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 supprime la variable transmise à case ... _ .

15voto

Sid Points 5659

Pour plus curieux

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é, le plus intéressant est qu'il n'est pas nécessaire de pré-déclarer des variables, ce qui est pratique si certaines valeurs ne vous intéressent pas.

10voto

Servé Laurijssen Points 1209

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 ne devez plus déclarer _ 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 _);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X