IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Chroniqueur Actualités

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2013
    Messages
    8 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Mars 2013
    Messages : 8 696
    Points : 202 429
    Points
    202 429
    Par défaut Microsoft dévoile des fonctionnalités de C# 7.0 opérationnelles dans Visual Studio “15” Preview 4
    Microsoft dévoile des fonctionnalités de C# 7.0 opérationnelles dans Visual Studio “15” Preview 4,
    comme les tuples ou encore le filtrage par motif

    Bien que C# 7.0 soit encore en développement, Microsoft a donné plus de détails sur des fonctionnalités qui, pour la plupart, sont déjà opérationnelles sur la préversion 4 de Visual Studio "15" qui a été proposée en téléchargement au courant de la semaine. La version 7.0 du langage orienté objet du framework .NET met un accent particulier sur la consommation de données, la simplification du code ainsi que la performance.

    C # 7.0 introduit la notion de patterns (modèles) que Microsoft décrit comme étant des éléments syntaxiques qui peuvent vérifier qu'une valeur a un certain « motif » et en extraire des informations une fois que la vérification est faite. Le filtrage par motif (pattern matching) permet de vérifier si l'objet du filtrage possède une structure donnée, s'il s'y trouve telle ou telle sous-structure spécifique et/ou éventuellement pour substituer quelque chose d'autre aux motifs reconnus. Comme exemple de filtres dans C # 7.0, Microsoft évoque :
    • les filtres constants de la forme c (où c est une expression constante dans C #), qui servent à vérifier que l’entrée est égale à c ;
    • les filtres de type T x (où T est un type et x un identifiant), qui servent à vérifier qu’une entrée est bien du type T et, si c’est le cas, extraire la valeur de l’entrée dans une nouvelle variable x de type T ;
    • les filtres de la forme var x (où x est un identifiant), qui effectuent toujours des correspondances et mettent simplement la valeur de l'entrée dans une variable x du même type que l'entrée.

    Voici un exemple avec un filtre constant et un filtre de type

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void PrintStars(object o)
    {
        if (o is null) return;     // filtre constant "null"
        if (!(o is int i)) return; // filtre de type "int i"
        WriteLine(new string('*', i));
    }

    Microsoft explique que les filtrages par motifs et les structures de contrôles vont souvent bien ensemble. Raison pour laquelle par exemple dans les instructions switch, qui permettent de tester plusieurs valeurs pour une expression, Microsoft a apporté des changements :
    • pour permettre d’effectuer un switch sur n’importe quel type (qui se limitait jusqu’à présent aux expressions de type scalaire comme les entiers, les caractères, les énumérations ou les booléens) ;
    • pour permettre d’utiliser des filtres dans les déclarations de série d’instructions (case) ;
    • pour permettre l’ajout de conditions additionnelles sur les clauses case.

    Voici un simple exemple :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    switch(shape)
    {
        case Circle c:
            WriteLine($"circle with radius {c.Radius}");
            break;
        case Rectangle s when (s.Length == s.Height):
            WriteLine($"{s.Length} x {s.Height} square");
            break;
        case Rectangle r:
            WriteLine($"{r.Length} x {r.Height} rectangle");
            break;
        default:
            WriteLine("<unknown shape>");
            break;
        case null:
            throw new ArgumentNullException(nameof(shape));
    }

    Microsoft apporte toutefois quelques précisions suite à l’extension de la structure de contrôle switch. Désormais, l’ordre des clauses case importe désormais, comme dans les clauses catch, étant donné que ces clauses ne sont plus nécessairement disjointes. De plus, comme dans les clauses catch, le compilateur va vous aider à repérer des cas évidents qui ne seront jamais atteints. La clause par défaut est toujours évaluée en dernier : dans l’exemple ci-dessus, bien que la clause « null » vienne en dernier, elle sera évaluée avant la clause par défaut.

    Les tuples, qui facilitent la possibilité de retourner plusieurs résultats, sont également annoncés comme étant l’un des changements les plus significatifs apportés avec cette version. Notons qu’avant la venue des tuples, il était possible de retourner plusieurs résultats. Cependant, les options n’étaient pas optimales. C# 7.0 proposent aux développeurs de se servir des littéraux et des types.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (string, string, string) LookupName(long id) // tuple return type
    {
        ... // va retirer first, middle et last from du stockage de données
        return (first, middle, last); // littéral du tuple
    }

    Cette méthode retourne trois chaînes de caractères encapsulées dans un tuple. Lors de l’appel de la méthode, la fonction pourra recevoir ce tuple et accéder à ses éléments individuels

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var names = LookupName(id);
    WriteLine($"found {names.Item1} {names.Item3}.");

    Item1 et etc. sont des noms par défaut des éléments d’un tuple et peuvent toujours être utilisés. Ils ne sont pas très descriptifs, il vous est possible de les modifier selon votre convenance. Par exemple

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    (string first, string middle, string last) LookupName(long id) // les éléments du tuple ont des noms

    Cette fois-ci, lors de l’appel de la méthode, il ne sera plus question de faire appel à Item1 mais plutôt :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var names = LookupName(id);
    WriteLine($"found {names.first} {names.last}.");

    Il est également possible de spécifier les noms directement dans les littéraux

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    return (first: first, middle: middle, last: last); // éléments nommés du tuple dans un littéral

    Pour gérer les tuples, une syntaxe de déclaration de déclaration de déconstruction permet aux développeurs de séparer le tuple (ou d’autres ensembles de valeurs) en plusieurs parts et assigner ces parts à de nouvelles variables.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (string first, string middle, string last) = LookupName(id1); // déclaration de déconstruction
    WriteLine($"found {first} {last}.");

    Dans une déclaration de déconstruction, il est possible d’utiliser var pour les variables individuelles déclarées :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    (var first, var middle, var last) = LookupName(id1); // var à l'intérieur

    Ou alors de choisir de mettre un seul var à l’extérieur des parenthèses

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    var (first, middle, last) = LookupName(id1); // var à l'extérieur

    Il est également possible de déconstruire un tuple dans des variables existantes en se servant d’une affectation de déconstruction :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    (first, middle, last) = LookupName(id2); // affectation de déconstruction

    Les améliorations au niveau du littéral permettent de se servir de « _ » comme séparateur de chiffres dans un littéral. Microsoft estime que cela permet d’améliorer la lisibilité et reste sans effet sur la valeur.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var d = 123_456;
    var x = 0xAB_CD_EF;

    En outre, C # 7.0 introduit la notion de littéraux binaires afin qu’il vous soit possible de spécifier les modèles de bit directement au lieu d’avoir à connaître la notation hexadécimale par cœur.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    var b = 0b1010_1011_1100_1101_1110_1111;

    Le nombre de types qui peuvent être retournés par des fonctions asynchrones a été étendu. Microsoft parle aussi des fonctions locales qui permettent aux développeurs de déclarer des fonctions auxiliaires dans le corps d’autres fonctions

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public int Fibonacci(int x)
    {
        if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));
        return Fib(x).current;
     
        (int current, int previous) Fib(int i)
        {
            if (i == 0) return (1, 0);
            var (p, pp) = Fib(i - 1);
            return (p + pp, p);
        }
    }

    Source : blog Microsoft

    Voir aussi :

    Visual Studio "15" Preview 4 est disponible, avec un nouveau moteur d'installation qui fait passer la taille de l'installation minimum à 400 Mo

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 41
    Points : 88
    Points
    88
    Par défaut
    Les améliorations concernant l'utilisation des tuples sont bienvenues.
    Il n'est pas rare d'avoir besoin de renvoyer un résultat "complexe" à partir d'une méthode et devoir créer un objet générique qui sera uniquement utiliser dans ce cas est fastidieux et sans grande valeur ajoutée. Ma réticence à utiliser les tuples actuellement était essentiellement due au fait que les noms des propriétés étaient très peu explicites et ça pouvait rendre la relecture du code extrêmement difficile dès lors qu'on utilisait des tuples à plus de 3 propriétés (et encore plus obscur si les propriétés en question étaient du même type).

  3. #3
    Membre averti Avatar de Jonyjack
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 149
    Points : 425
    Points
    425
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int i)) return; // filtre de type "int i"
    WriteLine(new string('*', i));
    Perso je trouve pas ça très clair de déclarer "i" et de lui affecter la valeur de "o" ainsi. Ce n'est pas si explicite à la lecture.
    Je trouve ça bien plus clair en l'écrivant ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int)) return;
    WriteLine(new string('*', (int)o));
    Pour le reste, c'est plutôt bienvenu

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 34
    Points : 12
    Points
    12
    Par défaut
    Je ne sais pas si vous avez déjà la réponse, mais est-ce qu'il sera possible d'utiliser C#7 avec visual studio community prochainement?
    Merci.

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Jonyjack Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int i)) return; // filtre de type "int i"
    WriteLine(new string('*', i));
    Perso je trouve pas ça très clair de déclarer "i" et de lui affecter la valeur de "o" ainsi. Ce n'est pas si explicite à la lecture.
    Je trouve ça bien plus clair en l'écrivant ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int)) return;
    WriteLine(new string('*', (int)o));
    La nouvelle ecriture me parait plutot logique, ca evite de devoir faire un cast derriere, comme ce serait le cas avec la solution que tu proposes (car is est deja implemente donc changer son comportement pourrait causer des problemes de retrocompatibilite).

  6. #6
    Membre émérite
    Inscrit en
    Janvier 2006
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 722
    Points : 2 727
    Points
    2 727
    Par défaut
    Citation Envoyé par DotNetMatt Voir le message
    La nouvelle ecriture me parait plutot logique, ca evite de devoir faire un cast derriere, comme ce serait le cas avec la solution que tu proposes (car is est deja implemente donc changer son comportement pourrait causer des problemes de retrocompatibilite).
    Le problème avec cette écriture, c'est qu'elle n'est pas cohérente avec la notion de bloc.

    Imaginons que j'écrive:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int i)) { ... quelque chose sans return } // filtre de type "int i"
    WriteLine(new string('*', i));
    quelle est ici la portée de la variable i?

    Ce qui serait plus logique ce serait d'avoir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (o is int i) { WriteLine(new string('*', i));return; } // filtre de type "int i"
    // et ici du code qui utilise o mais pas i
    Ainsi l'idée serait que le bloc commence à if et se termine avec l'accolade.

  7. #7
    Membre émérite
    Inscrit en
    Janvier 2006
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 722
    Points : 2 727
    Points
    2 727
    Par défaut
    Citation Envoyé par SaiRictus Voir le message
    Les améliorations concernant l'utilisation des tuples sont bienvenues.
    Il n'est pas rare d'avoir besoin de renvoyer un résultat "complexe" à partir d'une méthode et devoir créer un objet générique qui sera uniquement utiliser dans ce cas est fastidieux et sans grande valeur ajoutée. Ma réticence à utiliser les tuples actuellement était essentiellement due au fait que les noms des propriétés étaient très peu explicites et ça pouvait rendre la relecture du code extrêmement difficile dès lors qu'on utilisait des tuples à plus de 3 propriétés (et encore plus obscur si les propriétés en question étaient du même type).
    Le problème avec les tuples, c'est que la simplicité qu'ils apportent à celui qui écrit une fonction devient complexité pour celui qui l'utilise: si on a besoin que d'une des valeurs, on est obligé du coup d'utiliser la notation pointée:
    devient J'imagine déjà que beaucoup de gens vont écrire des fonctions du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (string result, int errorCode) f (...)
    ça rappelle les fonctions avec des paramètres par référence en Pascal, et je crois que c'est fréquent en Go par exemple. Sauf qu'en C# on n'a pas la construction (y, _) = f(x) avec une variable inutilisée, comme en Go.
    Alors que la bonne méthode en C#, c'est de lever une exception en cas d'erreur. Mais comme pour la plupart des gens le premier langage n'implémentait pas ce concept...

  8. #8
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 527
    Points : 5 195
    Points
    5 195
    Par défaut
    Les filtres... dubitatif je suis

    Le switch:
    bienvenu mais attention à la clarté du code

    Les tuples:
    Intérêt limité, les tuples existent déjà
    Si je veux nommer les variables autrement que par Item*, je retourne un type anonyme récupéré dans un dynamic
    Par la suite, je refactorise si nécessaire

    L'utilisation du underscore _ pour rendre plus lisible un litéral est une bonne idée, surtout pour les valeurs hex

    Enfin les litéraux binaires, il était temps.

  9. #9
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par esperanto Voir le message
    Le problème avec cette écriture, c'est qu'elle n'est pas cohérente avec la notion de bloc.

    Imaginons que j'écrive:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (!(o is int i)) { ... quelque chose sans return } // filtre de type "int i"
    WriteLine(new string('*', i));
    quelle est ici la portée de la variable i?

    Ce qui serait plus logique ce serait d'avoir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (o is int i) { WriteLine(new string('*', i));return; } // filtre de type "int i"
    // et ici du code qui utilise o mais pas i
    Ainsi l'idée serait que le bloc commence à if et se termine avec l'accolade.
    En effet, par contre sur le blog de Microsoft ils ecrivent :
    As you can see, the pattern variables – the variables introduced by a pattern – are similar to the out variables described earlier, in that they can be declared in the middle of an expression, and can be used within the nearest surrounding scope. [...]
    Qu'entendent-ils par "nearest surrounding scope" ? De ce que je comprend, comme pour une variable out, elle sera utilisable dans le bloc parent. Donc par exemple :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void PatternVariable()
    {
        if (!isDemo)
        {
            if (!(o is int i)) { ... quelque chose sans return } // filtre de type "int i"
            WriteLine(new string('*', i));
     
            // Dans ce bloc on peut utiliser i
        }
     
        // Ici i n'existe pas
    }
    Ce n'est qu'une supposition, je n'ai pas encore eu l'occasion de titiller la preview 4. Quelqu'un peut confirmer/infirmer ceci ?

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    468
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 468
    Points : 682
    Points
    682
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    Les tuples:
    Intérêt limité, les tuples existent déjà
    Si je veux nommer les variables autrement que par Item*, je retourne un type anonyme récupéré dans un dynamic
    Par la suite, je refactorise si nécessaire
    Mon dieu ! Utiliser du dynamic, c'est pour rire j'espère !? Vérifier le typage et les noms de variables à l'exécution quelle idée de génie Oo

    Sinon je n'ai pas pu encore bien étudier le truc mais j'espère qu'ils ont effectué un rapprochement entre les types anonymes et ces nouveaux tuples. A première vue les types anonymes devraient maintenant ne plus être anonymes.

  11. #11
    Membre émérite
    Inscrit en
    Janvier 2006
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 722
    Points : 2 727
    Points
    2 727
    Par défaut
    Citation Envoyé par DotNetMatt Voir le message
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void PatternVariable()
    {
        if (!isDemo)
        {
            if (!(o is int i)) { ... quelque chose sans return } // filtre de type "int i"
            WriteLine(new string('*', i));
     
            // Dans ce bloc on peut utiliser i
        }
     
        // Ici i n'existe pas
    }
    Il y a quand même un souci : dans la partie { ... quelque chose sans return } on peut utiliser i alors même que ce bloc n'est exécuté que si o n'est pas du bon type... alors i vaut quoi?

  12. #12
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par Stéphane le calme Voir le message
    Voici un exemple avec un filtre constant et un filtre de type

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void PrintStars(object o)
    {
        if (o is null) return;     // filtre constant "null"
        if (!(o is int i)) return; // filtre de type "int i"
        WriteLine(new string('*', i));
    }
    Je ne suis pas convaincu par les filtres de type. D'accord, cela apporte quelque chose, puisqu'il est possible de vérifier le type et de réaliser le cast en une seule opération, mais je trouve que cela pénalise la lecture du code. J'aurais bien vu l'assignation dans une variable déjà déclarée en lieu et place à la déclaration d'une variable au sein même du is. Pour ma part, je pense que je privilégierais les extensions de switch au lieu d'utiliser le filtre de type, et écrire ainsi quelque chose du style :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    switch(o)
    {
      case int i:
        WrilteLine(new string('*', i));
        break;
      default:
        break;
    }

    Par contre, le filtre constant me plait, même si dans l'exemple, il ne donne rien puisqu'on aurait pu écrire if (o == null) return;

    Et je n'ai pas compris à quoi servait le dernier type.

    Citation Envoyé par Stéphane le calme Voir le message
    Microsoft explique que les filtrages par motifs et les structures de contrôles vont souvent bien ensemble. Raison pour laquelle par exemple dans les instructions switch, qui permettent de tester plusieurs valeurs pour une expression, Microsoft a apporté des changements :
    • pour permettre d’effectuer un switch sur n’importe quel type (qui se limitait jusqu’à présent aux expressions de type scalaire comme les entiers, les caractères, les énumérations ou les booléens) ;
    • pour permettre d’utiliser des filtres dans les déclarations de série d’instructions (case) ;
    • pour permettre l’ajout de conditions additionnelles sur les clauses case.

    Voici un simple exemple :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    switch(shape)
    {
        case Circle c:
            WriteLine($"circle with radius {c.Radius}");
            break;
        case Rectangle s when (s.Length == s.Height):
            WriteLine($"{s.Length} x {s.Height} square");
            break;
        case Rectangle r:
            WriteLine($"{r.Length} x {r.Height} rectangle");
            break;
        default:
            WriteLine("<unknown shape>");
            break;
        case null:
            throw new ArgumentNullException(nameof(shape));
    }
    Une bonne nouvelle. Cela va permettre de remplacer des cascades de if par une structure bien plus lisible.

    Citation Envoyé par Stéphane le calme Voir le message
    Les tuples, qui facilitent la possibilité de retourner plusieurs résultats, sont également annoncés comme étant l’un des changements les plus significatifs apportés avec cette version. Notons qu’avant la venue des tuples, il était possible de retourner plusieurs résultats. Cependant, les options n’étaient pas optimales. C# 7.0 proposent aux développeurs de se servir des littéraux et des types.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (string, string, string) LookupName(long id) // tuple return type
    {
        ... // va retirer first, middle et last from du stockage de données
        return (first, middle, last); // littéral du tuple
    }
    Une bonne chose et une mauvaise chose. Bien utilisée, cette notion va apporter un gain en clarté. Mal utilisée par contre, se sera la profusion de types anonymes...

    Citation Envoyé par Stéphane le calme Voir le message
    Les améliorations au niveau du littéral permettent de se servir de « _ » comme séparateur de chiffres dans un littéral. Microsoft estime que cela permet d’améliorer la lisibilité et reste sans effet sur la valeur.

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var d = 123_456;
    var x = 0xAB_CD_EF;

    En outre, C # 7.0 introduit la notion de littéraux binaires afin qu’il vous soit possible de spécifier les modèles de bit directement au lieu d’avoir à connaître la notation hexadécimale par cœur.
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    var b = 0b1010_1011_1100_1101_1110_1111;
    Un gain indéniable pour la lisibilité. Je ne peux qu'approuver. Et la notation binaire était attendue depuis longtemps ! Cela va permettre de gagner aussi en clarté lors de la déclaration d'énumération de type drapeaux (Flags).

    Citation Envoyé par Stéphane le calme Voir le message
    Le nombre de types qui peuvent être retournés par des fonctions asynchrones a été étendu. Microsoft parle aussi des fonctions locales qui permettent aux développeurs de déclarer des fonctions auxiliaires dans le corps d’autres fonctions

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public int Fibonacci(int x)
    {
        if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));
        return Fib(x).current;
     
        (int current, int previous) Fib(int i)
        {
            if (i == 0) return (1, 0);
            var (p, pp) = Fib(i - 1);
            return (p + pp, p);
        }
    }
    Pour l'instant, je suis mitigé. Je vois des avantages (ça évite de définir une fonction qui ne sera utilisée que par une seule, et couplé avec les tuples, le gain est indéniable), mais aussi des inconvénients (cela alourdi le code de la fonction "mère"). Quoiqu'il en soit, l'exemple donné me laisse pantois, dans la mesure où la fonction Fib est utilisée avant d'être défini ! La lecture séquentielle du code en prend un sacré coup...

  13. #13
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 527
    Points : 5 195
    Points
    5 195
    Par défaut
    Citation Envoyé par ijk-ref Voir le message
    Mon dieu ! Utiliser du dynamic, c'est pour rire j'espère !? Vérifier le typage et les noms de variables à l'exécution quelle idée de génie Oo
    Tu as raison, c'est une vaste blague
    C'est sûr qu'un click de bouton qui réagit en 110ms au lieu de 100ms va pénaliser l'utilisateur

    Trêve de plaisanterie, on ne te demande pas non plus de l'utiliser à tout bout de champ, ni pour faire du temps réel
    Merci en tout cas pour ton ouverture d'esprit et ta critique constructive et détaillée

  14. #14
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    Tu as raison, c'est une vaste blague
    C'est sûr qu'un click de bouton qui réagit en 110ms au lieu de 100ms va pénaliser l'utilisateur
    Plus qu'un problème de performance, je pense que le soucis pour ijk-ref c'est que les erreurs de code ne seront pas remontés à la compilation par le compilateur, mais à l'exécution quand le programme va planter. D'un point de vue maintenance... il faut dire ce qui est, c'est très loin d'être l'idéal.

    Et de ce point de vue, je le rejoins.

  15. #15
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 527
    Points : 5 195
    Points
    5 195
    Par défaut
    Citation Envoyé par dorinf Voir le message
    Plus qu'un problème de performance, je pense que le soucis pour ijk-ref c'est que les erreurs de code ne seront pas remontés à la compilation par le compilateur, mais à l'exécution quand le programme va planter. D'un point de vue maintenance... il faut dire ce qui est, c'est très loin d'être l'idéal.

    Et de ce point de vue, je le rejoins.
    Les rares fois où j'ai rencontré le problème qui souvent est en rapport avec une typo, j'ai toujours eu un test unitaire qui me prévenait.
    Encore une fois, ce n'est pas un type que l'on utilise à tord et à travers.

  16. #16
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    Les rares fois où j'ai rencontré le problème qui souvent est en rapport avec une typo, j'ai toujours eu un test unitaire qui me prévenait.
    Dans un monde idéal oui. En pratique, encore faut-il
    1. avoir des tests unitaires ;
    2. qui couvrent 100% du code.


    La couverture à 100%, je ne l'ai jamais vu. Sur des portions de projet on peut l'atteindre, oui. Mais sur un projet dans sa globalité, non (par exemple, pour une application MVC, il faudrait tout tester, Modèle, Vue, Controller, et je n'ai jamais vu la vue testé).

    Et c'est à condition qu'on dispose de tests unitaires (et il y a plein de raisons pour ne pas en avoir).

    Et il faut qu'on puisse aussi les exécuter (petit clin d'oeil au bug de Visual Studio 2015 update 3 qui ne détectait plus la liste des tests unitaires en juillet. Heureusement qu'un patch est vite arrivé !).

    Citation Envoyé par shenron666
    Encore une fois, ce n'est pas un type que l'on utilise à tord et à travers.
    Je suis d'accord. Mais la réponse de ijk-ref était en réaction à
    Citation Envoyé par shenron666
    Si je veux nommer les variables autrement que par Item*, je retourne un type anonyme récupéré dans un dynamic
    Par la suite, je refactorise si nécessaire
    Clairement, pour moi, ce n'est pas pour cela qu'a été introduit le type dynamic. C'est un exemple d'une très mauvaise utilisation.

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    468
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 468
    Points : 682
    Points
    682
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    Tu as raison, c'est une vaste blague
    C'est sûr qu'un click de bouton qui réagit en 110ms au lieu de 100ms va pénaliser l'utilisateur
    La programmation ne se limite pas à l'écriture sommaire d'interfaces utilisateur. Elle doit permettre aussi l'écriture propre et efficace d'algorithmes. Ce que tu ne sembles pas avoir besoin mais pour d'autres cette fonctionnalité est un plus indéniable pour cette finalité.

    Citation Envoyé par shenron666 Voir le message
    Trêve de plaisanterie, on ne te demande pas non plus de l'utiliser à tout bout de champ, ni pour faire du temps réel
    Merci en tout cas pour ton ouverture d'esprit et ta critique constructive et détaillée
    Sympa de me parler d'ouverture d'esprit alors que tu souhaites me restreindre énormément l'utilisation de cette fonctionnalité !

    Je vais l'utiliser "à tout bout de champ" si je veux ! Surtout que contrairement à ce que tu crois cela a été assez étudié pour. Tu n'as vraiment pas l'air d'être conscient du potentiel de C# même pour du temps réel.

  18. #18
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Septembre 2016
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Septembre 2016
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Un peut faux.
    Bonjour,
    Je savais déja toutes ces fonctionnalité il y a plus d'un an c'est pas vraiment nouveau. Quand il y a des différence dans l'implementation on peut les suivre sur git/forum MS/... et même proposer sa solution. Le titre de cet article est donc faux "Microsoft dévoile ". Si on été sur Youtube il y aurais des "putaclic" partout dans les commentaire. Moi sa ne me géne pas c'est la desinformation entrainer qui me géne. En effet c'est la communauté C# et pas Microsoft tout seul qui a créer ces fonctionalité.
    De plus il y a des discution sur github pour parlé de ces fonctionnalitées. Sa aurais été (celon moi) la moindre des choses que de mettre le liens. Comme sa ceux qui ce dise "tien moi j'aurais plutot fais comme-ca" peuvent aller voir si sa n'a pas déja été proposé et peut être proposer.
    Pour les tuple par exemple : https://github.com/dotnet/roslyn/issues/347
    Cordialement

  19. #19
    Membre éprouvé
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Août 2014
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Août 2014
    Messages : 476
    Points : 1 042
    Points
    1 042
    Par défaut
    J'avoue toujours trouver ca un peu inutile tous ces changements de syntaxes en permanence.
    Ecrire en 1 ligne ce qu'on peut ecrire plus lisiblement en 3 je ne vois pas l'interet.
    Il y a 20 ans on nous expliquait quand on codait en C qu'il fallait eviter des syntaxes ou sur une meme ligne on essaie de faire rentrer plusieurs choses (et qu'au final le compilo generait de toutes façon un code tres proche - sans perte de perf).

    En 2016 ca semble etre ce qu'on recherche (pourtant le code ne tournera pas plus vite, sera encore moins lisible et source d'erreur (car tous les dev reprenant la maintenance n'auront pas forcement le meme niveau en C#).

    Je prefererai honnetement que Microsoft ne se perde pas dans ce genre de masturbation sur des "optimisations" de syntaxes (surtout qu'a l'heure actuelle les gains de productivité avec intellisense et autre resharper permettent de pisser du code sans meme trop connaitre les syntaxes); si M$ pouvait passer plus de temps sur des choses vraiment utiles et indispensables (genre un nouveau framework C++ desktop pour concurrencer QT) ?

  20. #20
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    468
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 468
    Points : 682
    Points
    682
    Par défaut
    Citation Envoyé par kilroyFR Voir le message
    J'avoue toujours trouver ca un peu inutile tous ces changements de syntaxes en permanence.
    Ecrire en 1 ligne ce qu'on peut ecrire plus lisiblement en 3 je ne vois pas l'interet.
    Il y a 20 ans on nous expliquait quand on codait en C qu'il fallait eviter des syntaxes ou sur une meme ligne on essaie de faire rentrer plusieurs choses (et qu'au final le compilo generait de toutes façon un code tres proche - sans perte de perf).

    En 2016 ca semble etre ce qu'on recherche (pourtant le code ne tournera pas plus vite, sera encore moins lisible et source d'erreur (car tous les dev reprenant la maintenance n'auront pas forcement le meme niveau en C#).

    Je prefererai honnetement que Microsoft ne se perde pas dans ce genre de masturbation sur des "optimisations" de syntaxes (surtout qu'a l'heure actuelle les gains de productivité avec intellisense et autre resharper permettent de pisser du code sans meme trop connaitre les syntaxes); si M$ pouvait passer plus de temps sur des choses vraiment utiles et indispensables (genre un nouveau framework C++ desktop pour concurrencer QT) ?
    Il n'y a aucun changement de syntaxes : tous codes des anciennes versions fonctionnent toujours.

    Et ça serait bien que tu donnes des exemples de ce que tu critiques. Car à mon avis aucunes nouvelles améliorations de syntaxe ne sont faites pour "faire rentrer plusieurs choses" Au contraire elles permettent de "faire rentrer une chose" sur une seule ligne alors qu'avant il en fallait plusieurs !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(o is Personne p && p.Age > 42)
    { 
      p.VerifierVaccins();
    }
    On n'a vraiment pas la même vision car pour moi ces "optimisations de syntaxes" rendre le code plus lisible et moins source d'erreur. Et je pense aussi que c'est un peu le but de Microsoft. Bizarre que t'arrives à voir l'inverse.

Discussions similaires

  1. Réponses: 0
    Dernier message: 31/03/2015, 17h39
  2. Microsoft ajoute des fonctionnalités aux Office Web Apps
    Par Gordon Fowler dans le forum Cloud Computing
    Réponses: 2
    Dernier message: 04/10/2011, 10h30
  3. Réponses: 1
    Dernier message: 29/07/2009, 18h38
  4. Réponses: 3
    Dernier message: 18/12/2006, 15h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo