2015-06-23 117 views
174

我打算使用逐字字符串,但是我錯誤地鍵入$而不是@

但編譯器沒有給我任何錯誤和編譯成功。

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

但是它不像一個逐字字符串,因爲我不能寫:

string str = $"text\"; 

有誰知道什麼$字符串前放置在C#。

string str = $"text"; 

我正在使用Visual Studio 2015 CTP。

回答

291

$是短手String.Format,並使用字符串插值,這是C#6中的新功能在你的情況下使用,它什麼也不做,就像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}"; 

也有一個選擇 - 少爲人知 - 使用[email protected]串插的形式(這兩個符號的順序很重要) 。它允許將@""字符串的功能與$""混合以支持字符串插值,而不需要在整個字符串中使用\\。所以以下兩行:

var someDir = "a"; 
Console.WriteLine([email protected]"c:\{someDir}\b\c"); 

將輸出:

c:\a\b\c 
+10

注意,它不是真正使用的String.Format,但它是一個編譯型的功能,而不是一個運行時。 –

+1

小問題,今天我學習了,如果你用'$ @',那麼你就用''''''''來強制轉義''',而當你只用'''時,情況就不是這樣了 – Flater

+0

@ Flater與$符號沒有任何關係,這與$ symbol存在之前的行爲是一樣的 – BVernon

14

這是插值字符串。您可以在任何可以使用字符串文字的地方使用插入的字符串。在運行程序時,將使用插值字符串文字執行代碼,代碼將通過評估插值表達式來計算新的字符串文字。每次執行插入字符串的代碼時都會執行此計算。

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

本示例生成一個字符串值,其中計算了所有字符串插值值。這是最後的結果,並有字符串類型。所有出現的雙曲花括號(「{{「 and 「}}」)都轉換爲單個花括號。

如果

string text = "One"; 

然後message含有 「樣本,一個」。

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

29

它創建一個interpolated string

MSDN

用於構造字符串。插入的字符串表達式看起來像一個包含表達式的模板字符串,它看起來像 。內插的 字符串表達式通過用表達式' 結果的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仍然相關。

+0

請注意,如果您將數據轉換爲字符串內的字符串,您可能仍然可以使用'$'並指定culture info使用正確的文化,例如'{somevar.ToString(...,[在此插入文化信息])'''表達式''' – jrh

6

請注意,您也可以將二者結合起來,這是很酷(儘管它看起來有點奇怪):

// simple interpolated verbatim string 
WriteLine([email protected]"Path ""C:\Windows\{file}"" not found."); 
+4

如果只是您可以決定鍵入'$ @'或'@的順序$''。'''''''''@''''''''''@ – Bauss

+1

@Bauss這是有道理的,'@'定義瞭如何表示字符串,'$'是'string.Format'的快捷方式,可以認爲它是'$ @「」);' – marsze

+0

這不是'string.Format'的一個快捷方式,它提供了一個解析爲'string.Format',所以它部分有意義,但不完全。 – Bauss

4

它標誌着串插。

它會保護你,因爲它在字符串評估上增加了編譯時間保護。

您將不再得到一個異常與string.Format("{0}{1}",secondParamIsMissing)

5

它比的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); 
} 
7

很酷的功能。我只想指出強調爲什麼這比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 「;」。

因此,它會更容易寫出這樣的代碼:

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

這會在緩存一個單一的字符串,而你必須非常容易閱讀的代碼。我不確定它的性能,但是,我相信MS會優化它,如果還沒有這樣做的話。

4

我不知道它是如何工作的,但你也可以用它來選擇你的價值!

例: 「這個」

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

當然,你可以更換與任何變量或任何有意義的東西,就像你也可以改變標籤一樣。

+0

是的,你也可以格式化字符串https://msdn.microsoft.com/en-us/library/dn961160.aspx –

0
using System; 

public class Example 
{ 
    public static void Main() 
    { 
     var name = "Horace"; 
     var age = 34; 
     var s1 = $"He asked, \"Is your name {name}?\", but didn't wait for a reply."; 
     Console.WriteLine(s1); 

     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. 
+0

Downvoted,對不起。如果你可以寫一些額外的描述你的代碼的評論,我會鼓勵它。 – AlexRebula

1

$語法很好,但有一個缺點。

如果您需要類似字符串模板的東西,那麼在類級別上聲明爲field ...以及它應該在一個地方。

然後,你必須聲明變量在同一水平......這不是很酷。

使用字符串更好。對於這樣的事情

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

使用全局變量的語法格式是不是真的OK

class Example2_$Format { 
    //must have declaration in same scope 
    string some = ""; 
    string thing = ""; 
    string template = $"{some} - {thing}"; 

    public string FormatExample1() { 
     some = "someone"; 
     thing = "something"; 
     return template; 
    } 

    public string FormatExample2() { 
     some = "someoneelse"; 
     thing = "somethingelse"; 
     return template; 
    } 
    } 
相關問題