Il existe un modèle dans les classes C # illustré par Dictionary.TryGetValue
et int.TryParse
: une méthode qui retourne un booléen indiquant le succès d'une opération et un paramètre out contenant le résultat réel; si l'opération échoue, le paramètre out est défini sur null.
Supposons que j'utilise des références C # 8 non nullables et que je souhaite écrire une méthode TryParse pour ma propre classe. La signature correcte est la suivante:
public static bool TryParse(string s, out MyClass? result);
Étant donné que le résultat est nul dans le faux cas, la variable out doit être marquée comme nullable.
Cependant, le modèle Try est généralement utilisé comme ceci:
if (MyClass.TryParse(s, out var result))
{
// use result here
}
Étant donné que je n'entre dans la branche que lorsque l'opération réussit, le résultat ne doit jamais être nul dans cette branche. Mais parce que je l'ai marqué comme nullable, je dois maintenant vérifier cela ou utiliser !
pour remplacer:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // compiler warning, could be null
Console.WriteLine("Look: {0}", result!.SomeProperty); // need override
}
C'est moche et un peu peu ergonomique.
En raison du modèle d'utilisation typique, j'ai une autre option: mentir sur le type de résultat:
public static bool TryParse(string s, out MyClass result) // not nullable
{
// Happy path sets result to non-null and returns true.
// Error path does this:
result = null!; // override compiler complaint
return false;
}
Maintenant, l'utilisation typique devient plus agréable:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // no warning
}
mais l'utilisation atypique ne reçoit pas l'avertissement qu'elle devrait:
else
{
Console.WriteLine("Fail: {0}", result.SomeProperty);
// Yes, result is in scope here. No, it will never be non-null.
// Yes, it will throw. No, the compiler won't warn about it.
}
Maintenant, je ne sais pas où aller ici. Y a-t-il une recommandation officielle de l'équipe de langage C #? Existe-t-il un code CoreFX déjà converti en références non nullables qui pourrait me montrer comment procéder? (Je suis allé chercher des TryParse
méthodes. IPAddress
Est une classe qui en a une, mais elle n'a pas été convertie sur la branche principale de corefx.)
Et comment le code générique Dictionary.TryGetValue
traite-t-il cela? (Peut-être avec un MaybeNull
attribut spécial de ce que j'ai trouvé.) Que se passe-t-il lorsque j'instancie un Dictionary
avec un type de valeur non nullable?
MyClass?
), et faites un interrupteur dessus avec uncase MyClass myObj:
et (un optionall)case null:
.