关于C#:字符串前的$是什么意思?

What does $ mean before a string?

我本来打算用逐字字符串,但我错打了$,而不是@

但是编译器没有给我任何错误,编译成功。

我想知道它是什么,它做什么。我找了找,但找不到任何东西。

但是它不像是逐字的字符串,因为我不能写:

1
string str = $"text";

有人知道C_中字符串前的$代表什么吗?

1
string str = $"text";

我正在使用Visual Studio 2015 CTP。


$String.Format的简称,用于字符串插值,这是c 6的一个新特性。正如在您的案例中使用的那样,它什么也不做,就像string.Format()什么也不做一样。

当用于构建引用其他值的字符串时,它是自己的。以前必须写的是:

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

现在变成:

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

另外还有一种使用$@的字符串插值形式(这两个符号的顺序很重要)。它允许@""字符串的特性与$""混合,以支持字符串插入,而不需要在字符串中使用\\。所以下面两行:

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

意志产出:

1
c:\a\b\c


它创建一个内插字符串。

来自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.

前任:

1
2
3
4
 var name ="Sam";
 var msg = $"hello, {name}";

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

可以在插值字符串中使用表达式

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

它的好处在于,您不需要像处理String.Format那样担心参数的顺序。

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

现在,如果你想删除一些参数,你必须去更新所有的计数,这已经不是问题了。

请注意,如果您想在格式中指定文化信息,好的旧String.Format仍然是相关的。


它是内插字符串。可以在任何可以使用字符串文字的地方使用内插字符串。当运行程序时,将使用插入字符串文本来执行代码,代码通过计算插入表达式来计算新的字符串文本。每次执行带有内插字符串的代码时都会进行此计算。

1
var message = $"Sample, {text}";

此示例生成一个字符串值,其中计算了所有字符串插值值。它是最终结果,具有类型字符串。所有出现的双花括号("{{" and"}}")都转换为单花括号。

如果,

1
string text ="One";

那么,message包含"样本,一个"。

1
Console.WriteLine(message); // Sample, One

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

1
2
3
Full name - Albert Einstein
Full name - Albert Einstein
Full name - Albert Einstein

参考-msdn


酷的特点。我只是想强调一下,如果有些人不清楚,为什么这比string.format更好。

我看到有人说order string.format to"0 1 2"匹配参数。您不必在string.format中强制订购"0 1 2",您也可以订购"2 0 1"。但是,如果您有很多参数,比如20,那么您真的希望将字符串排序为"0 1 2…"{ 19 }。如果这是一个混乱的混乱,你将很难排队你的参数。

使用$,可以在不计算参数的情况下直接添加参数。这使得代码更容易阅读和维护。

$的缺点是,不能轻易地在字符串中重复参数,必须键入它。例如,如果您厌倦了键入system.environment.newline,则可以执行string.format("…0…0…0",system.environment.newline),但在$中,必须重复它。不能执行"0"并将其传递给string.format,因为"0"返回"0"。

在旁注中,我已经阅读了另一个复制的tpoic中的注释。我无法评论,所以,给你。他说

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

创建多个字符串对象。事实上这不是真的。如果在一行中执行此操作,它只创建一个字符串并将其放置在字符串缓存中。

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

它们都返回一个字符串,并且只在缓存中创建一个值。

另一方面:

1
2
3
4
string+= string2;
string+= string2;
string+= string2;
string+= string2;

在缓存中创建4个不同的值,因为有4";"。

因此,像下面这样编写代码会更容易,但是您将创建五个内插字符串作为Carlos Mu?奥兹修正:

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

这会在缓存中创建一个字符串,而您可以很容易地读取代码。我不确定性能,但我相信微软会优化它,如果还没有优化的话。


请注意,您也可以将这两者结合起来,这非常酷(尽管看起来有点奇怪):

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


它比string.format更方便,您也可以在这里使用intellisense。

enter image description here

下面是我的测试方法:

1
2
3
4
5
6
7
8
9
10
[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);
}


$语法很好,但有一个缺点。

如果您需要类似于字符串模板的东西,它在类级别上声明为字段…在一个应该的位置。

然后你必须在同一个级别上声明变量……这不是很酷。

对于这种情况,使用string.format语法更好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
 }
}

使用globals并不是很好,除此之外-它也不适用于globals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 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;
 }
}


下面的例子强调了在清洁度和可读性方面,使用内插字符串比使用string.Format()的各种优势。它还显示了{}中的代码和其他任何函数参数一样被评估,就像我们被调用string.Format()时一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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.


我不知道它是如何工作的,但你也可以用它来标记你的价值观!

例子:

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

当然,你可以换成"这个!"使用任何变量或任何有意义的内容,就像您还可以更改选项卡一样。


它表示字符串插值。

它将保护您,因为它正在对字符串计算添加编译时保护。

你再也不会得到string.Format("{0}{1}",secondParamIsMissing)的例外。


字符串中的$符号用于定义插入字符串,这是C中插入字符串的一个功能。该字符串是可能包含插入表达式的"真字符串"。

有关更多信息,这是答案和示例的来源:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

希望它有帮助从2018