Comment insérer une nouvelle ligne dans une chaîne littérale?

155

Dans .NET, je peux fournir les deux \rou des \nchaînes littérales, mais il existe un moyen d'insérer quelque chose comme un caractère spécial "nouvelle ligne" comme Environment.NewLineune propriété statique?

Capitaine Comic
la source
9
Quelle est la question?
iburlakov

Réponses:

319

Eh bien, les options simples sont:

  • string.Format:

    string x = string.Format("first line{0}second line", Environment.NewLine);
  • Concaténation de chaînes:

    string x = "first line" + Environment.NewLine + "second line";
  • Interpolation de chaîne (en C # 6 et supérieur):

    string x = $"first line{Environment.NewLine}second line";

Vous pouvez également utiliser \ n partout et remplacer:

string x = "first line\nsecond line\nthird line".Replace("\n",
                                                         Environment.NewLine);

Notez que vous ne pouvez pas en faire une constante de chaîne , car la valeur de Environment.NewLinene sera disponible qu'au moment de l'exécution.

Jon Skeet
la source
1
Eh bien, merci bien sûr, mais je voulais dire éviter d'utiliser Environment.NewLine, ma question était de savoir s'il existe un littéral '/ newline'.
Captain Comic
2
@Captain: Pourquoi voulez-vous éviter Environment.NewLine? Bien au contraire, c'est une bonne pratique de l'utiliser
abatishchev
18
@abatishchev: Dans certains endroits, c'est une bonne pratique. Dans mes autres, ce n'est pas le cas. Vous devez vraiment savoir que vous souhaitez utiliser la plate-forme spécifique. Par exemple, ce n'est pas une bonne idée si vous utilisez un protocole réseau qui devrait définir lui-même les terminaisons de ligne.
Jon Skeet
1
@Captain Comic: Ma dernière phrase explique pourquoi il ne peut pas s'agir d'un échappement littéral - vous ne pouvez pas l'inclure dans les métadonnées d'une constante de chaîne, car ce n'est pas une valeur constante.
Jon Skeet
1
Ouais, j'étais peut-être réticent à cause des deux options: l'une utilisant l'opérateur plus et la seconde utilisant la méthode Format sont assez lourdes où l'injection du littéral '\ newline' serait le moyen le plus rapide. Mais comme Jon l'a dit, le littéral NewLine, s'il existait, devrait être dynamique et dépendant de la plate-forme.
Captain Comic
33

Si vous voulez une chaîne const qui contient Environment.NewLine, vous pouvez faire quelque chose comme ceci:

const string stringWithNewLine =
@"first line
second line
third line";

ÉDITER

Puisque c'est dans une chaîne de const, cela est fait au moment de la compilation, c'est donc l'interprétation du compilateur d'une nouvelle ligne. Je n'arrive pas à trouver une référence expliquant ce comportement, mais je peux prouver que cela fonctionne comme prévu. J'ai compilé ce code à la fois sur Windows et Ubuntu (avec Mono) puis démonté et voici les résultats:

Démonter sous Windows Démonter sur Ubuntu

Comme vous pouvez le voir, dans Windows, les nouvelles lignes sont interprétées comme \ r \ n et sur Ubuntu comme \ n

Tal Jérôme
la source
1
Le compilateur ajoute automatiquement un Environment.NewLine entre chaque ligne du texte. Ainsi, la chaîne est interprétée comme: "première ligne" + Environment.NewLine + "deuxième ligne" + Environment.NewLine + "troisième ligne"
Tal Jerome
3
+1 Manière peu connue d'insérer des nouvelles lignes dans les chaînes littérales. Y a-t-il une référence pour le comportement que vous spécifiez? Est-ce vraiment Environment.NewLine ou est-ce la définition du compilateur d'une nouvelle ligne?
Grimace of Despair
1
Êtes-vous sûr que ce n'est pas le caractère de nouvelle ligne de l'éditeur de code qui y est inséré? Si vous copiez-collez ce code dans un éditeur sous Windows, il sera probablement converti en \ r \ n. Faites de même sur une plate-forme de type Unix et elle sera probablement convertie en \ n à la place.
Xiyng
Attention à ça. Si vous vérifiez le code sur le serveur CI / CD (comme Teamcity, le contrôle côté serveur), il changera CRLF en LF et il n'y aura pas de nouvelles lignes dans la chaîne.
Leszek P
13
var sb = new StringBuilder();
sb.Append(first);
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append(second);
return sb.ToString();
abatishchev
la source
2
Pourquoi feriez-vous cela plutôt que d'utiliser first + Environment.NewLine + secondce qui est plus efficace et (IMO) plus facile à lire?
Jon Skeet
@Jon: Plus efficace, vraiment? Je pensais que String.Formatcela produirait 1 chaîne à la fois (mais c'est en interne un peu lent à cause des concaténations spécifiques à la culture, etc.), tandis que la concaténation de chaînes - 1 résultant + 1 temporaire, non?
abatishchev
1
@abatishchev: le compilateur convertit str + str + str en String.Concatenate, qui construit directement une seule chaîne de sortie (IIRC, si les chaînes sont littérales, la concaténation est effectuée dans le compilateur.
Richard
@Richard: c'est-à-dire que les concaténations de chaînes multiples mais sur une ligne ( "a"+b+"c"+d, etc.) par performance sont égales à une seule? Ou simplement converti en String.Concatenate(a,b,c,d,etc), non?
abatishchev
@abatishchev: C'est pourquoi je n'ai pas suggéré string.Formatdans le commentaire. La concaténation de chaînes ne produira aucune chaîne temporaire, car le compilateur appellera string.Concat(first, Environment.NewLine, second).
Jon Skeet
3

Un autre moyen de placement pratique de Environment.NewLine dans une chaîne de format. L'idée est de créer une méthode d'extension de chaîne qui formate la chaîne comme d'habitude, mais remplace également {nl} dans le texte par Environment.NewLine

Usage

   " X={0} {nl} Y={1}{nl} X+Y={2}".FormatIt(1, 2, 1+2);
   gives:
    X=1
    Y=2
    X+Y=3

Code

    ///<summary>
    /// Use "string".FormatIt(...) instead of string.Format("string, ...)
    /// Use {nl} in text to insert Environment.NewLine 
    ///</summary>
    ///<exception cref="ArgumentNullException">If format is null</exception>
    [StringFormatMethod("format")]
    public static string FormatIt(this string format, params object[] args)
    {
        if (format == null) throw new ArgumentNullException("format");

        return string.Format(format.Replace("{nl}", Environment.NewLine), args);
    }

Remarque

  1. Si vous souhaitez que ReSharper met en évidence vos paramètres, ajoutez un attribut à la méthode ci-dessus

    [StringFormatMethod ("format")]

  2. Cette implémentation est évidemment moins efficace que simplement String.

  3. Peut-être que l'un d'entre eux, intéressé par cette question, serait également intéressé par la question suivante: mise en forme de chaîne nommée en C #

MajesticRa
la source
2
string myText =
    @"<div class=""firstLine""></div>
      <div class=""secondLine""></div>
      <div class=""thirdLine""></div>";

ce n'est pas ça:

string myText =
@"<div class=\"firstLine\"></div>
  <div class=\"secondLine\"></div>
  <div class=\"thirdLine\"></div>";
Hakkı Eser
la source
1
static class MyClass
{
   public const string NewLine="\n";
}

string x = "first line" + MyClass.NewLine + "second line"

la source
3
-1: Le système définit déjà Environment.NewLine- voir les autres réponses.
Richard
@Richard: OP, pour autant que je puisse le comprendre, veut utiliser une chaîne littérale en ligne, c'estconst string
abatishchev
@Richard Environment.NewLine is static not const
1

les nouvelles versions .net vous permettent d'utiliser $ devant le littéral, ce qui vous permet d'utiliser des variables à l'intérieur comme suit:

var x = $"Line 1{Environment.NewLine}Line 2{Environment.NewLine}Line 3";
DanielK
la source
1
Un peu de contexte ne serait pas mauvais.
croxy du
1
Cela ne répond pas à la question. Une fois que vous aurez une réputation suffisante, vous pourrez commenter n'importe quel message ; à la place, fournissez des réponses qui ne nécessitent pas de clarification de la part du demandeur . - De l'avis
H. Pauwelyn
@ H.Pauwelyn ツ: Merci pour les commentaires. J'ai ajouté un peu de contexte. De mon point de vue, la solution répond définitivement à la question.
DanielK du
0

Si vous voulez vraiment que la chaîne New Line soit une constante, vous pouvez le faire:

public readonly string myVar = Environment.NewLine;

L'utilisateur du mot clé readonly en C # signifie que cette variable ne peut être affectée qu'une seule fois. Vous pouvez trouver la documentation à ce sujet ici . Il permet la déclaration d'une variable constante dont la valeur n'est connue qu'au moment de l'exécution.

assistant07KSU
la source
0

J'aime plus la "voie pythonique"

List<string> lines = new List<string> {
    "line1",
    "line2",
    String.Format("{0} - {1} | {2}", 
        someVar,
        othervar, 
        thirdVar
    )
};

if(foo)
    lines.Add("line3");

return String.Join(Environment.NewLine, lines);
percebus
la source
0

Si vous travaillez avec une application Web, vous pouvez essayer ceci.

StringBuilder sb = new StringBuilder();
sb.AppendLine("Some text with line one");
sb.AppendLine("Some mpre text with line two");
MyLabel.Text = sb.ToString().Replace(Environment.NewLine, "<br />")
Tejas Bagade
la source
0

Si je comprends la question: couple "\r\n"pour obtenir cette nouvelle ligne ci-dessous dans un textbox. Mon exemple a fonctionné -

   string s1 = comboBox1.Text;     // s1 is the variable assigned to box 1, etc.
   string s2 = comboBox2.Text;

   string both = s1 + "\r\n" + s2;
   textBox1.Text = both;

Une réponse typique pourrait être s1 s2 dans le text boxstyle de type défini.

Charles F
la source
-1

Ici, Environment.NewLine ne fonctionne pas.

Je mets un « < br / > » dans une chaîne et travaillé.

Ex:

ltrYourLiteral.Text = "Première ligne <. br / > Deuxième ligne.";

Fábio
la source