Longues lignes d'interpolation de chaîne en C # 6

134

J'ai trouvé que si l'interpolation de chaîne est vraiment agréable lorsqu'elle est appliquée aux appels de format de chaîne de ma base de code existante, étant donné la limite de colonne généralement préférée, la chaîne devient rapidement trop longue pour une seule ligne. Surtout lorsque les expressions interpolées sont complexes. Avec une chaîne de format, vous avez une liste de variables que vous pouvez diviser en plusieurs lignes.

var str = string.Format("some text {0} more text {1}",
    obj1.property,
    obj2.property);

Quelqu'un a-t-il un moyen préféré de briser ces lignes?

Je suppose que vous pourriez faire quelque chose comme:

var str = $"some text { obj1.property }" +
  " more text { obj2.property };
Jérémie Gowdy
la source
1
D'après mon expérience, il vaut mieux éviter d'interpoler des expressions complexes. Extrayez plutôt une variable dans ce cas. Si vous faites cela et que vous rompez là où vous avez des nouvelles lignes dans vos chaînes, cela ira généralement bien.
markijbema
2
Je suis confus par cette question. Je veux juste une multiligne $""qui fonctionne comme@""
Colonel Panic
2
Colonel Panic, la question est de savoir comment briser les longues lignes d'interpolation afin de ne pas violer les exigences de largeur de colonne, sans introduire de sauts de ligne dans la chaîne littérale elle-même. $ @ "" est génial mais toute nouvelle ligne introduite dans celle-ci sera dans la chaîne littérale.
Jeremiah Gowdy
4
Danger: $"some text { obj1.property }" + " more text { obj2.property }";ne fait pas ce que vous semblez penser. Seule la première moitié de cette expression est une chaîne interpolée; il est ensuite concaténé avec la chaîne littérale non interpolée" more text { obj2.property }"
bacar
1
Pour soutenir \ t \ r \ n dans $ @ voir la question stackoverflow.com/questions/51991713/…
M.Hassan

Réponses:

198

Vous pouvez diviser la ligne en plusieurs lignes, mais je ne dirais pas que la syntaxe est plus belle.

Vous devez utiliser la $@syntaxe pour utiliser une chaîne verbatim interpolée , et vous pouvez placer des retours à la ligne à l'intérieur des {...}paramètres, comme ceci:

string s = $@"This is all {
    10
    } going to be one long {
    DateTime.Now
    } line.";

La chaîne ci-dessus ne contiendra aucune nouvelle ligne et aura en fait un contenu comme celui-ci:

Tout cela va être une longue ligne 01.08.2015 23.49.47.

(note, format norvégien)

Maintenant, cela dit, je ne cesserais pas d'utiliser string.Format. À mon avis, certaines de ces expressions d'interpolation de chaîne semblent vraiment bonnes, mais les plus complexes commencent à devenir très difficiles à lire. Étant donné qu'à moins que vous ne l'utilisiez FormattableString, le code sera de toute façon compilé dans un appel à String.Format, je dirais de continuer String.Formatlà où cela a du sens.

Lasse V. Karlsen
la source
Réponse solide. Je suis presque sûr que cela FormattableStringse résume à un appel à String.Formattrop.
Alex Booker
8
Cette réponse m'a aidé à comprendre comment faire exactement le contraire. Merci pour la $@""syntaxe!
Bobson
@AlexBooker C'est plus complexe que ça. Vous ne pouvez pas le faire FormattableString.Invarian($"Hello {name}" + \n "are you the owner of {pet}?");car il fusionne les deux chaînes interpolées en une seule chaîne simple.
ANeves
Les nouvelles lignes et les tabulations sont respectées dans les chaînes verbatim interpolées. Entrez ce qui suit dans la fenêtre interactive C # et la chaîne résultante sera formatée:. > var name = "Simon"; var templateName = "How to interpolate a verbatim string"; var now = DateTime.UtcNow;. var output = $@"Hi {name}, This template is a demo of {templateName}. It was ran at {now.ToString("o")}"; > output. La sortie est"Hi Simon,\r\nThis template is a demo of How to interpolate a verbatim string.\r\n\r\nIt was ran at 2020-01-24T15:49:35.6678353Z"
Enzoaeneas le
1
@Enzoaeneas Je pense que vous avez surestimé la prise en charge du formatage dans les commentaires, mais je comprends et suis d'accord avec ce que vous dites.
Lasse V. Karlsen le
61

Vous pouvez combiner $et @ensemble pour obtenir une interpolation de chaîne et un littéral de chaîne multiligne:

var str = $@"some text { obj1.property }
     more text { obj2.property }";

Mais cela vous donnera un NewLinepersonnage entre les deux, donc ce n'est peut-être pas ce que vous voulez.

MarcinJuraszek
la source
3
Mais @ ne met-il pas réellement le saut de ligne dans le littéral?
Jeremiah Gowdy
5
Cela fait. J'ai mis à jour ma réponse pour le dire explicitement.
MarcinJuraszek
Non seulement une nouvelle ligne mais aussi le (s) onglet (s) initial (s) de la nouvelle ligne. Afin de représenter correctement le format de chaîne réel lors de l'utilisation $@"dans Visual Studio, vous devez commencer chaque nouvelle ligne à l'extrême gauche de l'éditeur de texte.
GDS
Avec cette solution, vous ne pouvez pas utiliser par exemple \ r et \ n dans la chaîne
Johan Franzén
22

Alors qu'OP a demandé autre chose, je m'attends à ce que de nombreuses personnes lisant cette question aimeraient une interpolation multiligne $""qui fonctionne comme @"". Pour ce faire, utilisez$@""

$@"Height: {height}
Width: {width}
Background: {background}"
Colonel Panic
la source
3
Il ne veut pas de nouvelles lignes dans la sortie, juste le code lui-même pour s'enrouler sur différentes lignes
Martin Capodici
7
Il a précisé que cette réponse était destinée au public qui vient chercher comment créer des chaînes multilignes en utilisant la syntaxe d'interpolation de chaîne.
Brandon Bonds
2

Ça y est:

var str = $"some text { obj1.property }" +
          $" more text { obj2.property }";

Notez le deuxième $dans le$"..." + $"..."

CallMeLaNN
la source
18
Notez que cela fera deux appels à String.Format et créera également trois chaînes en mémoire (Side A, Side B et A + B)
Kevin Kalitowski
1
Cela ne vous empêcherait-il pas d'utiliser un FormattableStringcast sur la chaîne concaténée?
binki
4
Dans de nombreuses implémentations d'aujourd'hui, fonctionnant sur un processeur GHz avec Gb de mémoire, un appel supplémentaire et une chaîne supplémentaire ne vous poseront pas de problèmes de performances. Les problèmes de performances seront causés par exemple par l'utilisation d'un algorithme de O (n2). Je pense qu'il est injuste de voter contre ce type.
Johan Franzén
1

J'ai utilisé StringBuilder dans ToString () remplacé comme exemple.

    // return employee data
    public override string ToString()
    {
        StringBuilder buffer = new StringBuilder();
        buffer.AppendLine($"Number: {EmployeeNumber}");
        buffer.AppendLine($"Name: {EmployeeName}");
        buffer.AppendLine($"Address: {PostalAddress}");
        buffer.AppendLine($"Phone: {PhoneNumber}");
        buffer.AppendLine($"Age: {EmployeeAge}");
        buffer.AppendLine($"Gender: {EmployeeGender}");
        buffer.AppendLine($"Status: {EmployeeStatus}");
        buffer.AppendLine($"Manager: {EmployeeManager}");
        buffer.AppendLine($"Start: {EmployeeStartDate.ToShortDateString()}");
        return buffer.ToString();
    }
Christopher Govender
la source
alors pourquoi pas buffer.AppendFormat("{0}Number: {1}", Environment.NewLine, EmployeeNumber);???
TS