String interpolations in C#
Enable string interpolations in C#.
The interpolation should happen during compile time, so there are no performance penalties paid during runtime.
The Boo implemenation is a good place to start:
http://boo.codehaus.org/String+Interpolation
These should work:
var a = "Now is $(DateTime.Now)."
var b = "Tomorrow will be $(DateTime.Now.AddDays(1))"
var c = "This list has $(list.Count()) items."
29 comments
-
Jamshid Asadzadeh
commented
I share your thoughts
-
Giovanni Bassi
commented
@David Boarman
It works fine, but it is insufficient. Code readability suffers with string.format. Also, this is a really small change that Microsoft could add to make the language more elegant. Plus all the other things I have already replied on this topic before (see below). -
David Boarman
commented
What is wrong with String.Format?
var a = string.Format("Now is {0}", DateTime.Now);
var b = string.Format("Tomorrow will be {0}", DateTime.Now.AddDays(1));
var c = string.Format("This list has {0} items.", list.Count()); -
Giovanni Bassi
commented
@ThomasX
The term is well known in the computer science world and used by many computer languages and experts: http://en.wikipedia.org/wiki/String_interpolationOfficial sites:
CoffeeScript:
http://coffeescript.org/#strings
PHP:
http://php.net/manual/en/language.types.string.php
Ruby:
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-php/It is not because you don't know it, that it is wrong.
Apparently, some uninformed programmer did not study enough. -
ThomasX
commented
Why is this called interpolation? It should be called substitution. Apparently some script kiddie is trying to impress with his half-knowledge.
-
Anonymous
commented
Old post is old, but using the Razor syntax (@) may prove more consistent with newer (at least that) part of the .NET ecosystem.
var a = "Now is @(DateTime.Now)";
var b = "Tommorow will be @(DateTime.Now.AddDays(1))"; -
Giovanni Bassi
commented
@Anonymous,
First of all, it is quite depressing that we can't have an open discussion and still have to face faceless people.
Still, users of languages that have that disagree with you. You might not be talking to any of them, so I deeply encourage you, if you can leave your anonymous house. They find it quite useful, as it really is. Also, this is the 6th most demanded feature in C# in uservoice. Right now, up to 358 people may disagree with you as well.
Also, it does make it more readable, it may allow to specify format if we specify it this way, and it can be made equally powerful.
And C# is becoming a scripting language as well, please see project Roslyn. It is coming. But it has nothing to do with that, this feature has nothing to do with scripting. You might need to work on a few different projects and platforms to realize that. -
Anonymous
commented
This seems useless. The syntax is less readable than string.Format("It's {0}", DateTime.Now); or manual concatenation "It's " + DateTime.Now. It is also less powerful, as with string formatting, the format specifier can perform custom formatting (decimal precision, zero padding, etc).
It would insert identifiers into literal strings, which make symbolic searches much less clear/straight forward.
C# is not a scripting language, and there are already two functionally equivalent means by which to do this. If creating these kinds of strings is your biggest annoyance when writing code, then you are either doing something wrong, or writing extremely simple applications.
-
Qwertie
commented
As people have mentioned, the syntax "It's $(DateTime.Now)" would require an annotation like $"It's $(DateTime.Now)" to avoid changing the meaning of the dollar sign in existing code. Unfortunately, it would be easy to forget the extra dollar sign. That's why I suggest instead:
string theTime = "It's \(DateTime.Now)";
This code is illegal in C# 5.0, so C# 6.0 could easily support it. However, the syntax conundrum would still remain for @"verbatim" strings.
If the C# team supports this, they should provide a way to choose a formatting function:
[assembly:InterpolatedStringFormatter("System.String.Format")]
...implying the translation
string theTime = String.Format("It's {0}", DateTime.Now);
Customization would be useful to plug in something for debugging or, more importantly, internationalization:
[assembly:InterpolatedStringFormatter("I18N.Translate")]
class I18N {
public const string[] SpanishMappings = new[] {
"It's {0}", "Son las {0}", ...
};
public string Translate(string fmt, params object[] args) { ... }
} -
Giovanni Bassi
commented
@Phillippe
You can still interpolate resources using string.format.
But I see no reason to use resources for a single language app, as most of them are. It would be naive to believe that this is not a common use case, we should optimize for it, not fight it. -
Philippe
commented
For serious application that would get translated in multiple languages, almost all strings should come from resource file and should allows parameters to be reordered.
Doing that would only make things worst if someday you have to translate your application. Better to do it the correct way from the beginning.
And even if the application will never be translated, it is still better to put strings in resources as it separated the text from the code.
-
ac
commented
C#-scripty - typing:
<Now is ´DateTime.Now´.
equals to:
WriteAlias("Now is "+DateTime.Now+".");
Where WriteAlias is a method that can be overriden to write to console or another place.
-
Gordon Tucker
commented
I would hate it if
"Now is $(" + "DateTime.Now)."
didn't equal
"Now is $(DateTime.Now)."I'd be fine if there was a prefix to the quotes that used this though
$"Now is $(DateTime.Now)." -> String.Format("Now is {0}", DateTime.Now) -
Justin Chase commented
@Tahir @AD, you're clearly wrong here. String interpolation is superior. Most modern languages have it and it makes C# seem a lot less cool to not have it. Are you nay-saying just for the heck of it now?
@Boogaloo It doesn't even make sense to have a String.Interpolate( ) method because the interoplation is done at compile time not runtime. It's transformed into a call to String.Format.
var s = "Hello $name";
is compiled as:
var s = string.Format(CultureInfo.Invariant, "Hello {0}", name);
String interpolation is that simple. Take anything after a $ and treat it as an expression and replace it with {index}.
Boom done.
-
Tahir Ahmadov
commented
@Giovanni,
I think it's less readable, not more readable. Take your example:
var c = $"This list has $(list.Count()) items."
Change it to:
var c = "This list has "+list.Count() + " items."
I just don't see that much of a difference either way.Compiler could (and probably should) make those guesses even for the + operator.
-
Giovanni Bassi
commented
@Tahir
It is not as readable as it is in string interpolations. When you have small string like that it makes little difference. Take a longer one with several placeholders and you are going to take longer. So why not have the language to help?
Also, the compiler could make some smart guesses. Noticing a large string and several concatenations, the compiler might use a StringBuilder instead of doing a string concat.
String templates are options, but first, not everyone uses them (and you are not the one going to force them to do it), and second, they do not fit every scenario. -
Tahir Ahmadov
commented
I guess my question would be, what is wrong with ..
x = "Date is " + date.ToShortDateString();
.. ?
If it's for debug purposes only, just concat stuff together - who cares about performance or readability?
And if it's for production use, then string templates are a better choice anyways, - resources, or some data-driven approach, like email templates, with placeholders, in XML or XSLT format, etc. etc.
-
Boogaloo
commented
@Giovanni: I like the $"blah blah" syntax. I would still like to see a method on the String class for it.. like String.Interpolate()... that way the $"blah blah" syntax would just be language-specific syntactic sugar that called a bcl method. Then languages that did not include syntax support could still target the new framework and take advantage of the new functionality.
-
NN
commented
Nemerle language : https://github.com/rsdn/nemerle/ has this too.
But much more options. http://nemerle.org/Lexical_structure_%28ref%29#String_interpolation_i.e._.24-notation -
Giovanni Bassi
commented
@Boogaloo,
We could maybe try a new string delimiter for strings with interpolation, instead of double quotes.
Maybe something like the pound (#):
var c = #This list has $(list.Count()) items.#
Or any other delimiter that makes sense, like %, $ or maybe used with the double quotes, as the @ is currently used:
var c = $"This list has $(list.Count()) items."
Another option would be a compiler directive that would be turned off on project migration, but turned on for new projects.