270
votes

I was going to use verbatim string but i mistakenly typed $ instead of @.

But the Compiler didn't give me any Error and Compiled successfully.

I want to know what it is and what it does. I searched for it but i couldn't find anything.

However it is not like a verbatim string because I can't write:

string str = $"text\";

Does anyone know what $ before string stand for in C#.

string str = $"text";

I'm using Visual studio 2015 CTP.

11

11 Answers

450
votes

$ is short-hand for String.Format and is used with string interpolations, which is a new feature of C# 6. As used in your case, it does nothing, just as string.Format() would do nothing.

It is comes into its own when used to build strings with reference to other values. What previously had to be written as:

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

Now becomes:

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

There's also an alternative - less well known - form of string interpolation using $@ (the order of the two symbols is important). It allows the features of a @"" string to be mixed with $"" to support string interpolations without the need for \\ throughout your string. So the following two lines:

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

will output:

c:\a\b\c
39
votes

It creates an interpolated string.

From MSDN

Used to construct strings. An interpolated string expression looks like a template string that contains expressions. An interpolated string expression creates a string by replacing the contained expressions with the ToString represenations of the expressions’ results.

ex :

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

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

You can use expressions within the interpolated string

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

The nice thing about it is that you don't need to worry about the order of parameters as you do with String.Format.

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

Now if you want to remove some parameters you have to go and update all the counts, which is not the case anymore.

Note that the good old string.format is still relevant if you want to specify cultural info in your formatting.

19
votes

Example 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}");

Output

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

It is Interpolated Strings. You can use an interpolated string anywhere you can use a string literal. When running your program would execute the code with the interpolated string literal, the code computes a new string literal by evaluating the interpolation expressions. This computation occurs each time the code with the interpolated string executes.

Following example produces a string value where all the string interpolation values have been computed. It is the final result and has type string. All occurrences of double curly braces (“{{“ and “}}”) are converted to a single curly brace.

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

After executing above 2 lines, variable message contains "Hello, World".

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

Reference - MSDN

10
votes

Cool feature. I just want to point out the emphasis on why this is better than string.format if it is not apparent to some people.

I read someone saying order string.format to "{0} {1} {2}" to match the parameters. You are not forced to order "{0} {1} {2}" in string.format, you can also do "{2} {0} {1}". However, if you have a lot of parameters, like 20, you really want to sequence the string to "{0} {1} {2} ... {19}". If it is a shuffled mess, you will have a hard time lining up your parameters.

With $, you can add parameter inline without counting your parameters. This makes the code much easier to read and maintain.

The downside of $ is, you cannot repeat the parameter in the string easily, you have to type it. For example, if you are tired of typing System.Environment.NewLine, you can do string.format("...{0}...{0}...{0}", System.Environment.NewLine), but, in $, you have to repeat it. You cannot do $"{0}" and pass it to string.format because $"{0}" returns "0".

On the side note, I have read a comment in another duplicated tpoic. I couldn't comment, so, here it is. He said that

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

creates more than one string objects. This is not true actually. If you do this in a single line, it only creates one string and placed in the string cache.

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

All of them return a string and only creates one value in the cache.

On the other hand:

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

Creates 4 different values in the cache because there are 4 ";".

Thus, it will be easier to write code like the following, but you would create five interpolated string as Carlos Muñoz corrected:

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

This creates one single string in the cache while you have very easy to read code. I am not sure about the performance, but, I am sure MS will optimize it if not already doing it.

8
votes

Note that you can also combine the two, which is pretty cool (although it looks a bit odd):

// simple interpolated verbatim string
WriteLine($@"Path ""C:\Windows\{file}"" not found.");
6
votes

It is more convenient than string.Format and you can use intellisense here too.

enter image description here

And here is my test method:

[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);
}
6
votes

It signifies string interpolation.

It will protect you because it is adding compilation time protection on the string evaluation.

You will no longer get an exception with string.Format("{0}{1}",secondParamIsMissing)

6
votes

The following example highlights various advantages of using interpolated strings over string.Format() as far as cleanliness and readability goes. It also shows that code within {} gets evaluated like any other function argument, just as it would if string.Format() we're being called.

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.
6
votes

$ syntax is nice, but with one downside.

If you need something like a string template, that is declared on the class level as field...well in one place as it should be.

Then you have to declare the variables on the same level...which is not really cool.

It is much nicer to use the string.Format syntax for this kind of things

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);
 }
}

The use of globals is not really ok and besides that - it does not work with globals either

 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;
 }
}
5
votes

I don't know how it works, but you can also use it to tab your values !

Example :

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

Of course, you can replace "this !" with any variable or anything meaningful, just as you can also change the tab.

0
votes

the $ sign in the string is for definition of interpolation string that is a feature in C# to interpolate the string is a "true string" that might contain interpolated expressions

for further information this is the source of the answer and example: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated