J'aime utiliser pattern-matching
sur un nullable int
i.e. int?
:
int t = 42;
object tobj = t;
if (tobj is int? i)
{
System.Console.WriteLine($"It is a nullable int of value {i}");
}
Cependant, cela entraîne les erreurs de syntaxe suivantes:
«i)» est marqué d'une ligne ondulée rouge.
L'expression est compilée lors de l'utilisation de l'ancien opérateur is
:
int t = 42;
object tobj = t;
if (tobj is int?)
{
System.Console.WriteLine($"It is a nullable int");
}
string t = "fourty two";
object tobj = t;
if (tobj is string s)
{
System.Console.WriteLine($@"It is a string of value ""{s}"".");
}
Fonctionne également comme prévu.
(J'utilise c # -7.2 et testé avec les deux .net-4.7.1 et .net-4.6.1 )
Je pensais qu'il y avait quelque chose à faire avec la préséance de l'opérateur. Par conséquent, j'ai essayé d'utiliser des parenthèses à plusieurs endroits mais cela n'a pas aidé.
Pourquoi donne-t-il ces erreurs de syntaxe et comment puis-je les éviter?
Le modèle de type sous ses différentes formes: x is T y
, case T y
etc, ne correspond toujours pas lorsque x
est null
. Cela est dû au fait que null
n'a pas le type , et demande donc "cette null
est-elle de ce type?" est une question dénuée de sens.
Par conséquent, t is int? i
ou t is Nullable<int> i
n'a pas de sens en tant que modèle: Soit t
est un int
, auquel cas t is int i
correspondra de toute façon, ou bien il s'agira de null
, auquel cas aucun modèle ne pourra correspondre.
Et c’est la raison pour laquelle t is int? i
ou t is Nullable<int> i
ne sont pas, et ne le seront probablement jamais, pris en charge par le compilateur.
La raison pour laquelle vous obtenez des erreurs supplémentaires du compilateur lorsque vous utilisez t is int? i
est due au fait que, par exemple, t is int? "it's an int" : "no int here"
est une syntaxe valide. Par conséquent, le compilateur ne comprend pas vos tentatives d'utilisation de ?
pour un type nullable dans ce contexte.
Pour ce qui est de savoir comment les éviter, la réponse évidente (bien que probablement pas très utile) est la suivante: n’utilisez pas de types nullable comme modèles de type. Une réponse plus utile vous obligerait à expliquer pourquoi vous essayez de le faire.
Changez votre code en:
int t = 42;
object tobj = t;
if (tobj is Nullable<int> i)
{
Console.WriteLine($"It is a nullable int of value {i}");
}
Cela produit le plus utile:
D'autres utilisateurs (utilisateur @ Blue0500 sur github ) ont balisé ce comportement en tant que bogue numéro Roslyn # 20156 . Réagissant au numéro Roslyn # 20156 , Julien Couvreur de Microsoft a déclaré qu'il pensait que c'était à dessein.
Neal Gafter de Microsoft travaillant sur Roslyn a également déclaré/ de meilleurs diagnostics sont nécessaires pour utiliser le type Nullable: switch pattern .
Donc, le message d'erreur peut être évité en utilisant:
int t = 42;
object tobj = t;
if (tobj == null)
{
Console.WriteLine($"It is null");
}
else if (tobj is int i)
{
Console.WriteLine($"It is a int of value {i}");
}
Sauf pour les problèmes lors de l'analysetobj is int? i
, la question de savoir pourquoi tobj is int? i
ou tobj is Nullable<int> i
n'est toujours pas laissée posée.