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

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Découvrir les futures fonctionnalités qui viendront avec C# 7.3
Qu'en pensez-vous ?

Le , par François DORIN

0PARTAGES

Un petit tour sur le GitHub du langage C# nous permet d'avoir un aperçu des nouvelles fonctionnalités pour la prochaine version du langage C# : la version 7.3.


Au jour d'aujourd'hui, ces fonctionnalités sont au nombre de 9. Les voici :
  • attributs sur le champ d'une propriété implémentée automatiquement ;
  • contrainte type non managé ;
  • variable out ;
  • amélioration de la résolution en cas de surcharge ;
  • réassignement des alias ;
  • autoriser l'initialisation de tableaux alloués sur la pile ;
  • opérateurs d'égalités == et != pour les tuples ;
  • améliorations autour du mot-clé fixed.


Attributs sur le champ d'une propriété implémentée automatiquement
Aujourd'hui, il n'est pas possible d'appliquer un attribut sur le champ d'une propriété implémentée automatiquement. Il est donc nécessaire d'écrire entièrement la propriété :
Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
[Serializable] 
public class Foo { 
    [NonSerialized] 
    private string MySecret_backingField; 
  
    public string MySecret { 
        get { return MySecret_backingField; } 
        set { MySecret_backingField = value; } 
    } 
}

Une des propositions de C# 7.3 serait la possibilité d'écrire le code suivant :
Code C# : Sélectionner tout
1
2
3
4
5
[Serializable] 
public class Foo { 
    [field: NonSerialized] 
    public string MySecret { get; set; } 
}
Ainsi, l'attribut sera appliqué un champ d'une propriété implémentée automatiquement et non sur la propriété elle-même. Cette approche est déjà utilisable pour les événements. Il s'agit donc uniquement d'une extension du langage.

Néanmoins il y a quelques soucis qui pourrait freiner son adoption. Aujourd'hui, cette syntaxe, bien que compilable, génère un avertissement et l'attribut est simplement ignoré. Autoriser cette écriture impliquerait donc un changement de comportement par rapport aux versions précédentes, qui pourrait avoir des conséquences en cas de recompilation de code, puisque l'attribut serait cette fois-ci pris en compte.

Contrainte type non managé
La contrainte "type non managé" permettrait de rendre générique du code qui aujourd'hui ne peut l'être. Cette fonctionnalité est à destination de développeurs de bibliothèques de bas niveau, notamment dans un cadre d'interopérabilité. Par exemple, elle permettrait de définir une méthode ainsi :
Code C# : Sélectionner tout
1
2
3
4
void Hash<T>(T value) where T : unmanaged 
{ 
    ... 
}

Aujourd'hui, ce n'est pas possible. Les développeurs sont donc obligé de générer autant de surcharges pour la méthode qu'il y a de types à supporter :
Code C# : Sélectionner tout
1
2
int Hash(Point point) { ... }  
int Hash(TimeSpan timeSpan) { ... }

Mais même si cela pourrait avoir des avantages sur la maintenance du code et sur les performances, cela pourrait avoir des répercutions sur l'ensemble de l'éco-système .NET. A voir donc si cette fonctionnalité sera maintenue dans la prochaine version du langage.

Variables out
C# 7 a introduit la possibilité de déclarer et d'utiliser une variable out en même temps, c'est-à-dire d'autoriser ce type de code :
Code C# : Sélectionner tout
1
2
3
4
if (int.TryParse(input, out int result)) 
    WriteLine(result); 
else 
    WriteLine("L'entrée n'est pas un entier");

Faute de temps pour mesurer correctement l'impact de ce type d'expression pour l'initialisation des attributs ou dans les constructeurs, cette possibilité n'avait pas été rendue possible. Ce sera maintenant chose possible avec C# 7.3, qui autorisera donc ce genre de code :
Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Collections.Generic; 
using System.Linq; 
  
public class A 
{ 
    public A(int i) 
    { 
    } 
  
    public static int Magic = int.TryParse("123", out var i) ? i : 0; 
} 
  
public class B : A 
{ 
    public B(string s) 
        : base(int.TryParse(s, out var i) ? i : 0) 
    { 
    } 
}

Amélioration en cas de surcharge
Les règles permettant de sélectionner la bonne méthode en cas de surcharge ont été affinées. Tout en gardant la rétrocompatibilité (sans quoi la recompilation de certains codes pourrait modifier leur comportement !), de nouvelles règles ont été ajoutées afin de résoudre automatiquement certains cas qui généraient une erreur jusqu'à présent.

Notamment, en cas de présence de membres statique et d'instance, seuls les membres pertinents sont sélectionnés. Ainsi, les surcharges statiques seront ignorées lors de l'appel d'une méthode via une instance et inversement.

De même, dans le cadre de la généricité, si les contraintes applicables au type sont incompatibles, la méthode sera ignorée (par exemple, une méthode générique acceptant un paramètre de type valeur ne sera pas retenue lors de la résolution si le paramètre fourni est de type référence).

Réassignement des alias
C# 7.2 a introduit la possibilité de créer des alias d'une variable. Par exemple, dans le code suivant :
Code C# : Sélectionner tout
ref int x = ref y;
les variables x et y sont tous simplement des alias.

Mais il n'était pas possible de réassigner un alias pour qu'il devienne un alias d'une autre variable. Ce sera a priori le cas avec C# 7.3, qui autorisera un réassignement :
Code C# : Sélectionner tout
1
2
ref int x = ref y; 
x = ref z; // redéfinition de l'alias. x est dorénavant équivalent à z, et non plus à y.

Autoriser l'initialisation de tableaux déclarés sur la pile
Il est possible de déclarer des tableaux sur la pile. Malheureusement, il n'est pas possible aujourd'hui de les initialiser. Cela sera possible avec la prochaine version de C#, qui lève cette restriction :
Code C# : Sélectionner tout
1
2
3
4
5
6
7
  
// actuellement valide 
stackalloc int[3];  
  
 // les déclarations suivantes seront valides avec la prochaine version de C# 
stackalloc int[3] { 1, 2, 3 }; 
stackalloc int[] { 1, 2, 3 };

Opérateurs d'égalité == et != pour les tuples
Une des propositions pour cette évolution du langage sera le support des opérateurs d'égalité (et donc d'inégalité) pour les tuples.

Ainsi, il sera possible d'écrire t1 == t2 qui serait alors traduit en un code sémantiquement équivalent (par exemple t1.Item1 == t2.Item1 && t1.Item2 == t2.Item2).

Amélioration de la prise en charge du mot clé fixed
Il y a également des nouveautés concernant l'utilisation du mot clé fixed.

D'une part, il ne sera plus nécessaire d'épingler une variable lors de l'accès à un de ses membres épinglé lorsque cet accès se fait via un index. Ainsi, dans le code suivant :
Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsafe struct S 
{ 
    public fixed int myFixedField[10]; 
} 
  
class Program 
{ 
    static S s; 
  
    unsafe static void Main() 
    { 
        int p = s.myFixedField[5]; // indexing fixed-size array fields would be ok 
    } 
}
Il ne sera pas nécessaire d'épingler la variable s avant de l'utiliser pour accéder au 6e élément de son attribut myFixedFiled.

Dans un autre ordre d'idée, mais toujours autour du mot clé fixed, il est envisagé un mécanisme permettant de préciser qu'un type utilisateur peut être épinglé et récupérer un pointeur natif et donc autoriser des codes comme :
Code C# : Sélectionner tout
1
2
3
4
5
fixed(byte* ptr = byteArray) 
{ 
   // ptr est un pointeur natif sur le premier élément du tableau. 
   // byteArray est protégé et ne peut être déplacé ou collecté par le ramasse-miettes pour toute la durée de ce bloc. 
}

Actuellement, les types autorisés dans cette construction sont codés en dur. L'idée serait donc d'assouplir cela et de permettre à un type nouvellement défini d'apparaitre dans ce type de construction. Cela servirait notamment pour des structures introduites récemment comme ImmutableArray<T> ou Span<T>.

Source : compte GitHub du projet C#

Et vous ?

Qu'en pensez-vous  ?
Quelles fonctionnalités souhaiteriez-vous voir en sus ?

Une erreur dans cette actualité ? Signalez-nous-la !