41 votes

Problèmes d'interpolation de chaîne

J'essaie de comprendre pourquoi mon test unitaire échoue (le troisième affirmation ci-dessous):

 var date = new DateTime(2017, 1, 1, 1, 0, 0);

var formatted = "{countdown|" + date.ToString("o") + "}";

//Works
Assert.AreEqual(date.ToString("o"), $"{date:o}");
//Works
Assert.AreEqual(formatted, $"{{countdown|{date.ToString("o")}}}");
//This one fails
Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");
 

D'après les informations dont je dispose, cela devrait fonctionner correctement, mais il semble que le paramètre de formatage ne soit pas transmis correctement. Il apparaît simplement comme {countdown|o} dans le code. Une idée pourquoi cela échoue?

2voto

Innat3 Points 1186

Le problème semble être que pour insérer une parenthèse lors de l'utilisation chaîne d'interpolation, vous vous devez d'y échapper par la dupliquer. Si vous ajoutez les parenthèses utilisées pour l'interpolation lui-même, nous nous retrouvons avec un triple parenthèse comme celui que vous avez dans la ligne qui vous donne l'exception:

Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");

Maintenant, si nous observons la "}}}", on peut remarquer que la première parenthèse, enferme la chaîne d'interpolation, tandis que les deux derniers sont destinés à être traitée comme une chaîne de caractères d'échappement parenthèse de caractère.

Le compilateur cependant, est de traiter les deux premières comme le scaped chaîne de caractères, donc c'est l'insertion d'une chaîne de caractères entre l'interpolation des délimiteurs. Fondamentalement, le compilateur est en train de faire quelque chose comme ceci:

string str = "a string";
$"{str'}'}"; //this would obviously generate a compile error which is bypassed by this bug

Vous pouvez résoudre ce problème en reformatant la ligne en tant que tel:

Assert.AreEqual(formatted, $"{{countdown|{$"{date:o}"}}}");

1voto

AQuirky Points 2070

C'est la meilleure façon de le faire valoir de travail...

Assert.AreEqual(formatted, "{" + $"countdown|{date:o}" + "}");

Dans ce formulaire...

Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");

Les 2 premiers de la fermeture des accolades sont interprétés comme un littéral accolade de fermeture et le troisième à la fermeture de la mise en forme de l'expression.

Ce n'est pas un bug tellement comme une limitation de la grammaire pour l'interpolation des chaînes de caractères. Le bug, si il y en a un, est que le résultat de la mise en forme de texte devrait probablement être "o}" au lieu de "o".

La raison pour laquelle nous avons l'opérateur "+=" au lieu de "=+" en C, C# et C++, c'est que dans la forme =+ on ne peut pas dire, dans certains cas, si le "+" est la partie de l'exploitant ou unaire "+".

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