字符串前$的含义是什么?

时间:2015-06-23 22:57:55

标签: c# string

我打算使用逐字字符串,但我错误地键入了$而不是@

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

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

然而,它不像一个逐字字符串,因为我无法写:

string str = $"text\";

有人知道C#中字符串代表之前的$

string str = $"text";

我正在使用Visual Studio 2015 CTP。

11 个答案:

答案 0 :(得分:373)

$String.Format的简写,用于字符串插值,这是C#6的一个新功能。在您的情况下,它不执行任何操作,就像{{1}一样什么都不做。

当用于构建引用其他值的字符串时,它就会出现。之前必须写的是:

string.Format()

现在变为:

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

还有另一种 - 不太为人所知 - 使用var anInt = 1; var aBool = true; var aString = "3"; var formated = $"{anInt},{aBool},{aString}"; 的字符串插值形式(两个符号的顺序很重要)。它允许$@字符串的功能与@""混合以支持字符串插值,而不需要在整个字符串中使用$""。所以以下两行:

\\

将输出:

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

答案 1 :(得分:36)

它会创建一个interpolated string

来自MSDN

  

用于构造字符串。内插字符串表达式   就像包含表达式的模板字符串一样。内插的   string表达式通过替换包含来创建一个字符串   具有ToString表达式表达式的表达式'   结果

前:

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

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

您可以在插值字符串

中使用表达式
 var msg = $"hello, {name.ToLower()}";
 Console.WriteLine(msg); // hello, sam

关于它的好处是你不必像对String.Format那样担心参数的顺序。

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

现在,如果你想删除一些参数,你需要更新所有的计数,但现在不再是这种情况了。

请注意,如果您想在formatting中指定文化信息,那么旧的string.format仍然相关。

答案 2 :(得分:16)

插值字符串。您可以在任何可以使用字符串文字的地方使用插值字符串。当运行程序时将使用插值字符串文字执行代码,代码通过计算插值表达式来计算新的字符串文字。每次执行内插字符串的代码时都会发生此计算。

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

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

如果,。

string text = "One";

然后message包含" Sample,One"。

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

实施例

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

输出

Full name - Albert Einstein
Full name - Albert Einstein
Full name - Albert Einstein

参考 - MSDN

答案 3 :(得分:10)

很酷的功能。我只想指出强调为什么这比string.format更好,如果对一些人来说不明显的话。

我读到有人说订单string.format到“{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中读到了评论。我无法评论,所以,在这里。他说那个

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

创建多个字符串对象。事实并非如此。如果您在一行中执行此操作,它只会创建一个字符串并放在字符串缓存中。

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

所有这些都返回一个字符串,只在缓存中创建一个值。

另一方面:

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

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

因此,编写如下代码会更容易,但是当CarlosMuñoz纠正时你会创建五个插值字符串:

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

这会在缓存中创建一个单独的字符串,同时您可以轻松读取代码。我不确定性能,但是,我确信MS会优化它,如果还没有这样做的话。

答案 4 :(得分:7)

请注意,您也可以将两者结合起来,这很酷(虽然看起来有点奇怪):

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

答案 5 :(得分:6)

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

enter image description here

这是我的测试方法:

[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 :(得分:5)

它表示字符串插值。

它会保护你,因为它正在为字符串评估添加编译时保护。

您将不再使用string.Format("{0}{1}",secondParamIsMissing)

获得例外

答案 7 :(得分:5)

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

示例:

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

当然,您可以替换“这个!”任何变量或任何有意义的东西,就像你也可以更改标签一样。

答案 8 :(得分:5)

以下示例强调了在string.Format()上使用插值字符串的各种优点,只要清洁度和可读性如此。它还显示{}中的代码与任何其他函数参数一样被评估,就像我们调用string.Format()时一样。

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.

答案 9 :(得分:5)

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

如果您需要类似字符串模板的内容,那么在类级别上将其声明为字段......在一个地方应该是这样。

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

使用string.Format语法来表达这种事情要好得多

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

使用全局变量并不是很好,除此之外 - 它不适用于全局变量

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="1080">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadiusRatio="3"
    android:shape="ring"
    android:thicknessRatio="8"
    android:useLevel="false">
    <size
        android:width="48dip"
        android:height="48dip" />
    <gradient
        android:angle="0"
        android:endColor="#A5865F"
        android:startColor="@android:color/transparent"
        android:type="sweep"
        android:useLevel="false" />
</shape>

答案 10 :(得分:0)

字符串中的$符号用于定义插值字符串,这是C#中用于插值字符串的功能,是可能包含插值表达式的“真字符串”

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

希望有帮助 从2018年起

相关问题