Given
IDictionary<string, string> x;
previously you could do (as an example of the parameter code having quote marks):
string.Format("{0}", x["y"]);
What is the proper way to format the C# 6.0 string interpolation?
$"{x["y"]}" // compiler error due to the quotes on the indexer value
// UPDATE: actually does work, must have had another typo I missed
Escaping the quotes as
\"
doesn't work, and doing
var b = "y";
...
$"{x[b]}"
seems awkward.
This works for me:
var dictionary= new Dictionary<string, string>();
dictionary.Add("x","value of x");
Console.WriteLine($"x is {dictionary["x"]}");
Make sure your project is set to use the version 6.0 of C# Language level (it's the default option on VS2015).
Edit: You can also try it here. (make sure you check the "C# 6.0 Beta").
Related
Today, I encountered this new syntax in a C# program:
var sb = new StringBuilder();
foreach (var ns in this.Namespaces)
{
_ = sb.AppendFormat(CultureInfo.InvariantCulture, " {0}", ns.Value);
}
The underscore inside the loop is never defined, and the code above seems to compile just fine.
So I think the underscore is a syntactic sugar of some kind. But seems that my Google skill failed me this time (I found perl and python information about underscore, or a JS library named underscore).
So it's not clear to me the meaning of the underscore in the code snippet. Can someone clarify it to me?
The code is taken from this library :
https://www.nuget.org/packages/OpenGraph-Net/4.0.2-alpha.0.6
A Net Core 6.0 library written in C#
The term you need to search for is discard variables - the underscore indicates that the variable is intentionally unused.
See here for more details.
Let's say I want to assign a text (which contains many double quotes) into variable. However, the only way seems to manually escape:
string t = "Lorem \"Ipsum\" dummy......
//or//
string t = #"Lorem ""Ipsum"" dummy.....
Is there any way to avoid manual escaping, and instead use something universal (which I dont know in C#) keywoard/method to do that automatically? In PHP, it's untoldly simple, by just using single quote:
$t = 'Lorem "Ipsum" dummy .......
btw, please don't bomb me with critiques "Why do you need to use that" or etc. I need answer to the question what I ask.
I know this answer may not be satisfying, but C# sytnax simply won't allow you to do such thing (at the time of writing this answer).
I think the best solution is to use resources. Adding/removing and using strings from resources is super easy:
internal class Program
{
private static void Main(string[] args)
{
string myStringVariable = Strings.MyString;
Console.WriteLine(myStringVariable);
}
}
The Strings is the name of the resources file without the extension (resx):
MyString is the name of your string in the resources file:
I may be wrong, but I conjecture this is the simplest solution.
No. In C# syntax, the only way to define string literals is the use of the double quote " with optional modifiers # and/or $ in front. The single quote is the character literal delimiter, and cannot be used in the way PHP would allow - in any version, including the current 8.0.
Note that the PHP approach suffers from the need to escape ' as well, which is, especially in the English language, frequently used as the apostrophe.
To back that up, the EBNF of the string literal in current C# is still this:
regular_string_literal '"' { regular_string_literal_character } '"'
The only change in the compiler in version 8.0 was that now, the order of the prefix modifiers $ (interpolated) and # (verbatim) can be either #$ or $#; it used to matter annoyingly in earlier versions.
Alternatives:
Save it to a file and use File.ReadAllText for the assignment, or embed it as a managed ressource, then the compiler will provide a variable in the namespace of your choice with the verbatim text as its runtime value.
Or use single quotes (or any other special character of your choice), and go
var t = #"Text with 'many quotes' inside".Replace("'", #"""");
where the Replace part could be modeled as an extension to the String class for brevity.
I've just come across this code in an article on .NET Core configuration, and the dictionary keys look very foreign to me:
static IReadOnlyDictionary<string, string> DefaultConfigurationStrings{get;} = new Dictionary<string, string>()
{
["Profile:UserName"] = Environment.UserName,
[$"AppConfiguration:ConnectionString"] = DefaultConnectionString,
[$"AppConfiguration:MainWindow:Height"] = "400",
[$"AppConfiguration:MainWindow:Width"] = "600",
[$"AppConfiguration:MainWindow:Top"] = "0",
[$"AppConfiguration:MainWindow:Left"] = "0",
};
Why the $ and why the [...]? Something to do with not using comma-separated key-value pairs?
The brackets are the new index initializers. It's just another way to initialize a dictionary that's a bit more readable than the collection initializers that have been there before.
As for the strings, when not using interpolations, it's just a simple string, nothing more. Presumably the compiler won't even generate the string.Format call for such strings. You can remove the $ just as well (it's the same with verbatim string literals when not using any of the different features).
One possible reason for the $"" strings might be, though, that it's a hint to either a source code preprocessor or static analysis tool that the string is somehow special. I've seen something similar used with verbatim string literals to prevent ReSharper from suggesting to translate the string for i18n. That's something you'd look for in your build environment, though.
After reading the following:
CLR Needed for C# 6.0
Does C# 6.0 work for .NET 4.0
it seemed to me that aside from String Interpolation any project I compiled in VS2015 against .NET 4.51 could use the new C# language features.
However I tried the following code on my dev machine using VS2015 targeting 4.51:
string varOne = "aaa";
string varTwo = $"{varOne}";
if (varTwo == "aaa")
{
}
and not only did I not receive a compiler error, it worked as varTwo contained aaa as expected.
Can someone explain why this is the case as I would not have expected this to work? I am guessing I am missing what FormattableString really means. Can someone give me an example?
As mentioned in the comments, string interpolation works in this case as all the new compiler does is convert the expression into an "equivalent string.Format call" at compile time.
From https://msdn.microsoft.com/en-us/magazine/dn879355.aspx
String interpolation is transformed at compile time to invoke an equivalent string.Format call. This leaves in place support for localization as before (though still with traditional format strings) and doesn’t introduce any post compile injection of code via strings.
The FormattableString is a new class allows you to inspect the string interpolation before rendering so you can check the values and protect against injection attacks.
// this does not require .NET 4.6
DateTime now = DateTime.Now;
string s = $"Hour is {now.Hour}";
Console.WriteLine(s);
//Output: Hour is 13
// this requires >= .NET 4.6
FormattableString fs = $"Hour is {now.Hour}";
Console.WriteLine(fs.Format);
Console.WriteLine(fs.GetArgument(0));
//Output: Hour is {0}
//13
Can someone explain why this is the case as I would not have expected this to work?
This works since you're compiling with the new Roslyn compiler which ships with VS2015, and knows how to parse the string interpolation syntactic sugar (it simply calls the proper overload of string.Format). If you'd try to take advantage of .NET Framework 4.6 classes that work nicely with string interpolation, such as FormattableString or IFormattable, you'd run into a compile time error (unless you add them yourself. See bottom part of the post).
I am guessing I am missing what FormattableString really means.
FormattableString is a new type introduced in .NET 4.6, which allows you to use the new string interpolation feature with a custom IFormatProvider of your choice. Since this can't be done directly on the interpolated string, you can take advantage of FormattableString.ToString(IFormatProvider) which can be passed any custom format.
I'm using System.Web.Script.Serialization.JavaScriptSerializer() to serialize dictionary object into JSON string. I need to send this JSON string to API sitting in the cloud. However, when we serialize it, serializer replaces all the double quotes with \"
For example -
Ideal json_string = {"k":"json", "data":"yeehaw"}
Serializer messed up json_string = {\"k\":\"json\",\"data\":\"yeehaw\" }
Any idea why it is doing so? And I also used external packages like json.net but it still doesn't fix the issues.
Code -
Dictionary<string, string> json_value = new Dictionary<string, string>();
json_value.Add("k", "json");
json_value.Add("data", "yeehaw");
var jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string json_string = jsonSerializer.Serialize(json_value);
I'm going to hazard the guess that you're looking in the IDE at a breakpoint. In which case, there is no problem here. What you are seeing is perfectly valid JSON; simply the IDE is using the escaped string notation to display it to you. The contents of the string, however, are your "ideal" string. It uses the escaped version for various reasons:
so that you can correctly see and identify non-text characters like tab, carriage-return, new-line, etc
so that strings with lots of newlines can be displayed in a horizontal-based view
so that it can be clear that it is a string, i.e. "foo with \" a quote in" (the outer-quotes tell you it is a string; if the inner quote wasn't escaped it would be confusing)
so that you can copy/paste the value into the editor or immediate-window (etc) without having to add escaping yourself
Make sure you're not double serializating the object. It happened to me some days ago.
What you're seeing is a escape character
Your JSON is a String and when you want to have " in a string you must use one of the following:
string alias = #"My alias is ""Tx3""";
or
string alias = "My alias is \"Tx3\"";
Update
Just to clarify. What I wanted say here is that your JSON is perfectly valid. You're seeing the special characters in the IDE and that is perfectly normal like Jon & Marc are pointing in their answers and comments. Problem lies somewhere else than those \ characters.