Que signifie $ avant une chaîne?

251

J'allais utiliser une chaîne textuelle mais j'ai tapé par erreur $au lieu de @.

Mais le compilateur ne m'a donné aucune erreur et a été compilé avec succès.

Je veux savoir ce que c'est et ce qu'il fait. Je l'ai cherché mais je n'ai rien trouvé.

Cependant, ce n'est pas comme une chaîne textuelle car je ne peux pas écrire:

string str = $"text\";

Est-ce que quelqu'un sait ce $que la chaîne représente en C #.

string str = $"text";

J'utilise Visual studio 2015 CTP.

M.kazem Akhgary
la source

Réponses:

419

$est un raccourci pour String.Formatet est utilisé avec des interpolations de chaînes, qui est une nouvelle fonctionnalité de C # 6. Comme utilisé dans votre cas, il ne fait rien, tout comme string.Format()ne ferait rien.

Il prend tout son sens lorsqu'il est utilisé pour créer des chaînes en référence à d'autres valeurs. Ce qui devait auparavant être écrit:

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = string.Format("{0},{1},{2}", anInt, aBool, aString);

Devient maintenant:

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = $"{anInt},{aBool},{aString}";

Il existe également une autre forme, moins connue, d'interpolation de chaînes $@ (l'ordre des deux symboles est important). Il permet de @""mélanger les fonctionnalités d'une chaîne pour prendre $""en charge les interpolations de chaîne sans avoir besoin de \\tout au long de votre chaîne. Donc, les deux lignes suivantes:

var someDir = "a";
Console.WriteLine($@"c:\{someDir}\b\c");

affichera:

c:\a\b\c
David Arno
la source
29
Notez qu'il n'utilise pas vraiment String.Format, mais est une fonctionnalité basée sur le compilateur, pas une exécution.
Shahar Prish
2
Petite note que j'ai apprise aujourd'hui, si vous utilisez $@, alors vous êtes obligé d'échapper au "personnage en utilisant "". Ce n'est pas le cas lorsque vous utilisez uniquement $.
Flater
3
@Flater Cela n'a cependant rien à voir avec le symbole $. C'est le même comportement qu'avant le symbole $.
BVernon
2
Pour votre point sur l'ordre de l'ordre des symboles verbatim (@) et interpolation ($) étant important, cela est corrigé en C # 8 afin que l'ordre ne soit plus important. Voir: devsanon.com/uncategorized/…
elkaz
39

Il crée une chaîne interpolée .

Depuis MSDN

Utilisé pour construire des chaînes. Une expression de chaîne interpolée ressemble à une chaîne de modèle qui contient des expressions. Une expression de chaîne interpolée crée une chaîne en remplaçant les expressions contenues par les représentations ToString des résultats des expressions.

ex:

 var name = "Sam";
 var msg = $"hello, {name}";

 Console.WriteLine(msg); // hello, Sam

Vous pouvez utiliser des expressions dans la chaîne interpolée

 var msg = $"hello, {name.ToLower()}";
 Console.WriteLine(msg); // hello, sam

La bonne chose à ce sujet est que vous n'avez pas à vous soucier de l'ordre des paramètres comme vous le faites avec String.Format.

  var s = String.Format("{0},{1},{2}...{88}",p0,p1,..,p88);

Maintenant, si vous voulez supprimer certains paramètres, vous devez aller mettre à jour tous les décomptes, ce qui n'est plus le cas.

Notez que le bon vieux string.formatreste pertinent si vous souhaitez spécifier des informations culturelles dans votre mise en forme .

Sleiman Jneidi
la source
Notez que vous pourriez probablement utiliser $et spécifier les informations de culture si vous convertissez vos données en chaîne à l'intérieur de l' $expression en utilisant la culture correcte, par exemple {somevar.ToString(...,[Insert culture info here])}.
2018 à
18

Exemple de code

public class Person {
    public String firstName { get; set; }
    public String lastName { get; set; }
}

// Instantiate Person
var person = new Person { firstName = "Albert", lastName = "Einstein" };

// We can print fullname of the above person as follows
Console.WriteLine("Full-Name - " + person.firstName + " " + person.lastName);
Console.WriteLine("Full-Name - {0} {1}", person.firstName, person.lastName);
Console.WriteLine($"Full-Name - {person.firstName} {person.lastName}");

Production

Full-Name - Albert Einstein
Full-Name - Albert Einstein
Full-Name - Albert Einstein

Il s'agit de chaînes interpolées . Vous pouvez utiliser une chaîne interpolée partout où vous pouvez utiliser un littéral de chaîne. Lorsque l'exécution de votre programme exécutait le code avec le littéral de chaîne interpolé, le code calcule un nouveau littéral de chaîne en évaluant les expressions d'interpolation. Ce calcul se produit à chaque exécution du code avec la chaîne interpolée.

L'exemple suivant produit une valeur de chaîne où toutes les valeurs d'interpolation de chaîne ont été calculées. Il s'agit du résultat final et de type chaîne. Toutes les occurrences de doubles accolades (“{{“ and “}}”)sont converties en une seule accolade.

string text = "World";
var message = $"Hello, {text}";

Après avoir exécuté plus de 2 lignes, la variable messagecontient "Hello, World".

Console.WriteLine(message); // Prints Hello, World

Référence - MSDN

Saveendra Ekanayake
la source
10

Fonction cool. Je veux juste souligner l'accent mis sur pourquoi c'est mieux que string.format s'il n'est pas évident pour certaines personnes.

J'ai lu quelqu'un disant order string.format à "{0} {1} {2}" pour faire correspondre les paramètres. Vous n'êtes pas obligé de commander "{0} {1} {2}" dans string.format, vous pouvez également faire "{2} {0} {1}". Cependant, si vous avez beaucoup de paramètres, comme 20, vous voulez vraiment séquencer la chaîne sur "{0} {1} {2} ... {19}". Si c'est un désordre mélangé, vous aurez du mal à aligner vos paramètres.

Avec $, vous pouvez ajouter des paramètres en ligne sans compter vos paramètres. Cela rend le code beaucoup plus facile à lire et à maintenir.

L'inconvénient de $ est que vous ne pouvez pas répéter facilement le paramètre dans la chaîne, vous devez le saisir. Par exemple, si vous en avez assez de taper System.Environment.NewLine, vous pouvez faire string.format ("... {0} ... {0} ... {0}", System.Environment.NewLine), mais, en $, vous devez le répéter. Vous ne pouvez pas faire $ "{0}" et le passer à string.format car $ "{0}" renvoie "0".

En passant, j'ai lu un commentaire dans un autre tpoic dupliqué. Je ne pouvais pas commenter, alors, le voici. Il a dit que

string msg = n + " sheep, " + m + " chickens";

crée plusieurs objets chaîne. Ce n'est pas vrai en fait. Si vous faites cela sur une seule ligne, il ne crée qu'une seule chaîne et est placé dans le cache de chaînes.

1) string + string + string + string;
2) string.format()
3) stringBuilder.ToString()
4) $""

Tous renvoient une chaîne et ne créent qu'une seule valeur dans le cache.

D'autre part:

string+= string2;
string+= string2;
string+= string2;
string+= string2;

Crée 4 valeurs différentes dans le cache car il y a 4 ";".

Ainsi, il sera plus facile d'écrire du code comme le suivant, mais vous créeriez cinq chaînes interpolées comme Carlos Muñoz l'a corrigé:

string msg = $"Hello this is {myName}, " +
  $"My phone number {myPhone}, " +
  $"My email {myEmail}, " +
  $"My address {myAddress}, and " +
  $"My preference {myPreference}.";

Cela crée une seule chaîne dans le cache alors que vous avez un code très facile à lire. Je ne suis pas sûr des performances, mais je suis sûr que MS l'optimisera s'il ne le fait pas déjà.

BoBoDev
la source
1
Votre dernier exemple est faux: en fait, vous créez deux chaînes: une à partir de la chaîne interpolée et l'autre à partir du reste des chaînes. Notez que seul celui avec {myName} est interpolé, les autres ne fonctionnent pas comme prévu.
Carlos Muñoz
1
Et si vous ajoutez $ aux 5 chaînes, il crée ensuite 5 chaînes interpolées chacune avec la leur String.Format(), puis concaténées au moment de l'exécution avec String.Concat. Il est donc préférable de ne pas le diviser en plusieurs lignes
Carlos Muñoz
1
Vous avez raison @Carlos Muñoz, je l'ai corrigé. Merci d'avoir rattrapé l'erreur.
BoBoDev
8

Notez que vous pouvez également combiner les deux, ce qui est plutôt cool (bien que cela semble un peu étrange):

// simple interpolated verbatim string
WriteLine($@"Path ""C:\Windows\{file}"" not found.");
marsze
la source
5
Si seulement vous pouviez décider de l'ordre dans lequel vous avez tapé $@ou @$. Malheureusement, cela ne peut être que$@
Bauss
2
@Bauss Cela a du sens. @définit comment représenter le littéral de chaîne. $est un raccourci pour string.Format. Pensez-y comme$(@"");
Marsze
Ce n'est pas vraiment un raccourci pour string.Format. C'est sucré pour présenter une valeur qui est analysée à un string.Format, donc cela a du sens en partie, mais pas entièrement.
Bauss
3
Je dis simplement que $c'est essentiellement un appel de fonction implicite alors qu'il @fait partie du littéral, tout comme mdans un littéral décimal. C'est pourquoi il n'y a qu'un seul ordre logique.
marsze
2
Je sais que c'était surtout juste ici pour démontrer $, mais dans un souci de compatibilité maximale et non de codage en dur si le séparateur de répertoire est '/' ou '\', et en évitant également le vissage inévitable provoquant une double barre oblique ou une barre oblique manquante là où il devrait ont été un, je recommande d'utiliser Path.Combine()au lieu d'utiliser des concaténations de chaînes lorsque vous travaillez avec des répertoires et des fichiers.
2018
6

C'est plus pratique que string.Format et vous pouvez également utiliser intellisense ici.

entrez la description de l'image ici

Et voici ma méthode de test:

[TestMethod]
public void StringMethodsTest_DollarSign()
{
    string name = "Forrest";
    string surname = "Gump";
    int year = 3; 
    string sDollarSign = $"My name is {name} {surname} and once I run more than {year} years."; 
    string expectedResult = "My name is Forrest Gump and once I run more than 3 years."; 
    Assert.AreEqual(expectedResult, sDollarSign);
}
GorkemHalulu
la source
6

Cela signifie une interpolation de chaîne.

Il vous protégera car il ajoute une protection de temps de compilation sur l'évaluation de la chaîne.

Vous n'aurez plus d'exception avec string.Format("{0}{1}",secondParamIsMissing)

argent
la source
6

L'exemple suivant met en évidence divers avantages de l'utilisation de chaînes interpolées en termes string.Format()de propreté et de lisibilité. Il montre également que le code à l'intérieur {}est évalué comme tout autre argument de fonction, comme s'il string.Format()était appelé.

using System;

public class Example
{
   public static void Main()
   {
      var name = "Horace";
      var age = 34;
      // replaces {name} with the value of name, "Horace"
      var s1 = $"He asked, \"Is your name {name}?\", but didn't wait for a reply.";
      Console.WriteLine(s1);

      // as age is an integer, we can use ":D3" to denote that
      // it should have leading zeroes and be 3 characters long
      // see https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-pad-a-number-with-leading-zeros
      //
      // (age == 1 ? "" : "s") uses the ternary operator to 
      // decide the value used in the placeholder, the same 
      // as if it had been placed as an argument of string.Format
      //
      // finally, it shows that you can actually have quoted strings within strings
      // e.g. $"outer { "inner" } string"
      var s2 = $"{name} is {age:D3} year{(age == 1 ? "" : "s")} old.";
      Console.WriteLine(s2); 
   }
}
// The example displays the following output:
//       He asked, "Is your name Horace?", but didn't wait for a reply.
//       Horace is 034 years old.
Pažout
la source
6

La syntaxe $ est agréable, mais avec un inconvénient.

Si vous avez besoin de quelque chose comme un modèle de chaîne, celui-ci est déclaré au niveau de la classe comme champ ... bien au même endroit comme il se doit.

Ensuite, vous devez déclarer les variables au même niveau ... ce qui n'est pas vraiment cool.

Il est beaucoup plus agréable d'utiliser la syntaxe string.Format pour ce genre de choses

class Example1_StringFormat {
 string template = $"{0} - {1}";

 public string FormatExample1() {
   string some1 = "someone";
   return string.Format(template, some1, "inplacesomethingelse");
 }

 public string FormatExample2() {
   string some2 = "someoneelse";
   string thing2 = "somethingelse";
   return string.Format(template, some2, thing2);
 }
}

L'utilisation de globaux n'est pas vraiment ok et en plus de cela - cela ne fonctionne pas non plus avec les globaux

 static class Example2_Format {
 //must have declaration in same scope
 static string some = "";
 static string thing = "";
 static string template = $"{some} - {thing}";

//This returns " - " and not "someone - something" as you would maybe 
//expect
 public static string FormatExample1() {
   some = "someone";
   thing = "something";
   return template;
 }

//This returns " - " and not "someoneelse- somethingelse" as you would 
//maybe expect
 public static string FormatExample2() {
   some = "someoneelse";
   thing = "somethingelse";
   return template;
 }
}
À M
la source
Cette réponse est importante car elle souligne que l'interpolation se produit lorsque vous "appelez" la chaîne $, pas lorsque vous la déclarez.
dx_over_dt
1
Vous avez raison sur l'anti-modèle de déclaration de vos variables d'interpolation au niveau de la classe, mais si ces variables appartiennent déjà en tant que propriétés de classe, ce modèle fonctionne bien.
dx_over_dt
@dx_over_dt Vous vous trompez. Les chaînes interpolées sont évaluées au moment où elles sont déclarées. C'est pourquoi l'exemple de code n'a aucun sens. Il ne compilera pas non plus.
NineBerry
@NineBerry Vous avez raison à la fois sur les chaînes interpolées évaluées au moment où elles sont déclarées et sur Example_ $ Format ne se compile pas et sur l'exemple de code n'a pas de sens :) J'ai corrigé l'exemple pour mieux l'expliquer.
Tom
5

Je ne sais pas comment cela fonctionne, mais vous pouvez également l'utiliser pour tabuler vos valeurs!

Exemple :

Console.WriteLine($"I can tab like {"this !", 5}.");

Bien sûr, vous pouvez remplacer "ceci!" avec n'importe quelle variable ou quelque chose de significatif, tout comme vous pouvez également changer l'onglet.

Een Amok
la source
oui, vous pouvez également formater la chaîne msdn.microsoft.com/en-us/library/dn961160.aspx
M.kazem Akhgary