Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's $-operator supposed to mean for a string?

Tags:

string

c#

So, I've just had the following conversation with a user in the comments section.

Me:

Year year = new Year{ State = States.Happy };

Them:

eventStream.ReceiveJoke += joke =>  
    Console.WriteLine($"Pretty nice joke: {joke}, Thanks!!!");

And, nerdy as I am, I wonder what he meant by the dollar sign but I think it's too embarrassing to ask him.

like image 649
Konrad Viltersten Avatar asked Jan 01 '16 18:01

Konrad Viltersten


4 Answers

It's an interpolated string literal, introduced in C# 6.

It's broadly equivalent to:

eventStream.ReceiveJoke += joke =>  
    Console.WriteLine(string.Format("Pretty nice joke: {0}, Thanks!!!", joke));

The compiler looks for braces within any string literal introduced with $, and applies string formatting to it. You can use (mostly) arbitrary expressions, rather than just variables, e.g.

Console.WriteLine($"{year.State} {2000 + 16}"); // Happy 2016
like image 157
Jon Skeet Avatar answered Oct 16 '22 07:10

Jon Skeet


It's the symbol that allow you to create a interpolated string, it's a new feature from C# 6, and I love it.

Also its a Syntax Sugar, I will explain what it mean in the end.

Lets see in action. look the following code

public string Receive(int value)
{
    return String.Format("Received: {0}", value);
}

public string Receive6(int value)
{
    return $"Received: {value}";
}

What happens what it is compiled

They will have the same IL implementation, look here the IL(in Debug mode, not optimized) from Receive

.method public hidebysig instance string Receive (int32 'value') cil managed 
{
    // Method begins at RVA 0x22d4
    // Code size 22 (0x16)
    .maxstack 2
    .locals init (
        [0] string
    )

    IL_0000: nop
    IL_0001: ldstr "Received: {0}"
    IL_0006: ldarg.1
    IL_0007: box [mscorlib]System.Int32
    IL_000c: call string [mscorlib]System.String::Format(string, object)
    IL_0011: stloc.0
    IL_0012: br.s IL_0014

    IL_0014: ldloc.0
    IL_0015: ret
} // end of method Program::Receive

Now lets see IL(in Debug mode, not optimized) from Receive6

.method public hidebysig instance string Receive6 (int32 'value') cil managed 
{
    // Method begins at RVA 0x22f8
    // Code size 22 (0x16)
    .maxstack 2
    .locals init (
        [0] string
    )

    IL_0000: nop
    IL_0001: ldstr "Received: {0}"
    IL_0006: ldarg.1
    IL_0007: box [mscorlib]System.Int32
    IL_000c: call string [mscorlib]System.String::Format(string, object)
    IL_0011: stloc.0
    IL_0012: br.s IL_0014

    IL_0014: ldloc.0
    IL_0015: ret
} // end of method Program::Receive6

As you can see with your own eyes, the IL is pretty much the same.

Now lets understand what is a Syntax Suggar

In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

From https://en.wikipedia.org/wiki/Syntactic_sugar

So instead to write the massive string.Format, use string interpolation, the compiler will work for you and convert the syntax that you wrote, in another code, in this case, using string.Format.

Can I use formatting options like in string.Format?

Yes, you can, look below

public static string Receive(int value) 
    => string.Format("Received: {0, 15:C}", value);

public static string Receive6(int value) 
    => $"Received: {value,15:C}";

Console.WriteLine(Receive(1));
Console.WriteLine(Receive6(1));
Console.WriteLine($"Current data: {DateTime.Now: MM/dd/yyyy}")

Output (my culture is pt-br)

Received:         R$ 1,00
Received:         R$ 1,00
Current data:  01/01/2016

Obs.: I would like to mention, there is not performance difference, since using string interpolation e string.Format is exactly the same thing

like image 24
Alberto Monteiro Avatar answered Oct 16 '22 07:10

Alberto Monteiro


In short, it is good way to improve the readability of the code and reduce its length. It's much better then String.Concat or + operator because string interpolation executes just one time as String.Format (and it is actually compile to String.Format method call) and you can just read the expression from left to right.

String.Format and its cousins are very versatile and useful, but their use is a little clunky and error prone. Particularly unfortunate is the use of {0} etc. placeholders in the format string, which must line up with arguments supplied separately:

var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);

String interpolation lets you put the expressions right in their place, by having “holes” directly in the string literal:

var s = $"{p.Name} is {p.Age} year{{s}} old";

Just as with String.Format, optional alignment and format specifiers can be given:

var s = $"{p.Name,20} is {p.Age:D3} year{{s}} old";

The contents of the holes can be pretty much any expression, including even other strings:

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

Notice that the conditional expression is parenthesized, so that the : "s" doesn’t get confused with a format specifier.

Via

like image 8
Vadim Martynov Avatar answered Oct 16 '22 09:10

Vadim Martynov


This is a new feature of C# 6 that is called string interpolation, which

lets you more easily format strings. String.Format and its cousins are very versatile, but their use is somewhat clunky and error prone.

For further information about this, please have a look here.

Example

Let that we have the following class:

public class Customer
{
    public int Id { get; set; }
    public string FirstName {get; set;}
    public string LastName { get; set; }
}

and let suppose that we want to ovveride the ToString method, like below:

public override string ToString()
{
    return string.Format("The customer with Id: {0} has as FirstName: {1} and as LastName: {2}", Id, FirstName,
            LastName);
}

In C# 6 we could have the same result using string interpolation.

public override string ToString()
{
    return $"The customer with Id: {Id} has as FirstName: {FirstName} and as LastName: {LastName}";
}

Benefits of string interpolation:

  • A string is significantly easier to read than a composite string.
  • There is a reduction in the syntax errors caused by arguments following the format string that are in improper order, or missing altogether and causing an exception.
like image 5
Christos Avatar answered Oct 16 '22 07:10

Christos