c# - 空白空值 - 空字串




在C#中,我應該使用string.Empty還是String.Empty或“”來intitialize一個字符串? (20)

最好的代碼根本就沒有代碼

編碼的基本性質是,作為程序員,我們的任務是認識到我們做出的每一個決定都是一種折衷。 [...] 從簡潔開始。 根據測試要求增加其他維度。

因此,更少的代碼是更好的代碼:首選""string.EmptyString.Empty 。 這兩個是六倍 ,沒有額外的好處 - 當然沒有增加清晰度,因為它們表達了完全相同的信息。

在C#中,我想用一個空字符串初始化一個字符串值。

我應該怎麼做? 什麼是正確的方式,為什麼?

string willi = string.Empty;

要么

string willi = String.Empty;

要么

string willi = "";

或者是什麼?


String.Emptystring.Empty是等效的。 String是BCL類名稱; string是它的C#別名(或者快捷鍵,如果你願意的話)。 與Int32int相同。 有關更多示例,請參閱文檔

""而言,我並不確定。

就我個人而言,我總是使用string.Empty


使用任何你和你的團隊發現的最具可讀性。

其他答案建議每次使用""時都會創建一個新字符串。 這不是真的 - 由於字符串interning,它會創建一個程序集或每個AppDomain一次(或可能一次為整個過程 - 不知道在這方面)。 這種差異是微不足道的 - 大量的, 大量的微不足道的。

但是,您發現更具可讀性的是另一回事。 這是主觀的,會因人而異 - 所以我建議你找出你的團隊中大多數人喜歡的東西,並且都是為了一致性。 我個人發現""更易於閱讀。

""" "很容易被誤認為對方的論點並不真正與我一起洗。 除非您使用比例字體(並且我沒有與任何開發人員合作),否則很容易區分。


一個區別是,如果您使用switch-case語法,則不能寫入case string.Empty:因為它不是常量。 您會收到一個Compilation error : A constant value is expected

查看此鏈接了解更多信息: string-empty-versus-empty-quotes


儘管差異非常小,但差異依然存在。

1)“”創建對象,而String.Empty不創建對象。 但是這個對象將會被創建一次,並且如果你在代碼中有另一個“”,它將在以後的字符串池中被引用。

2)字符串和字符串是相同的,但我會建議使用String.Empty(以及String.Format,String.Copy等),因為點符號表示類,而不是操作符,並且以大寫字母開頭的類符合C#編碼標準。


前兩者中的任何一個都可以接受。 我會避免最後一個,因為通過在引號之間放置空格來引入錯誤相對容易。 這個特殊的錯誤很難通過觀察找到。 假設沒有拼寫錯誤,所有都在語義上相同。

[編輯]

另外,您可能希望始終使用stringString來保持一致性,但這只是我自己。


幾乎每個開發者都會知道“”的含義。 我個人第一次遇到了String.Empty,並且不得不花費一些時間來搜索谷歌,以確定它們是否確實完全相同的東西。


從性能和代碼生成的角度來看,確實沒有什麼區別。 在性能測試中,他們之間來回切換,其中一個比另一個快,而且只有幾毫秒。

在查看幕後代碼時,你確實沒有看到任何區別。 唯一的區別是在IL中,哪個string.Empty使用操作碼ldsfld""使用操作碼ldstr ,但那隻是因為string.Empty是靜態的,並且兩個指令都執行相同的操作。 如果你看看生產的組件,它是完全一樣的。

C#代碼

private void Test1()
{
    string test1 = string.Empty;    
    string test11 = test1;
}

private void Test2()
{
    string test2 = "";    
    string test22 = test2;
}

IL代碼

.method private hidebysig instance void 
          Test1() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test1,
                [1] string test11)
  IL_0000:  nop
  IL_0001:  ldsfld     string [mscorlib]System.String::Empty
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test1
.method private hidebysig instance void 
        Test2() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test2,
                [1] string test22)
  IL_0000:  nop
  IL_0001:  ldstr      ""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test2

彙編代碼

        string test1 = string.Empty;
0000003a  mov         eax,dword ptr ds:[022A102Ch] 
0000003f  mov         dword ptr [ebp-40h],eax 

        string test11 = test1;
00000042  mov         eax,dword ptr [ebp-40h] 
00000045  mov         dword ptr [ebp-44h],eax 
        string test2 = "";
0000003a  mov         eax,dword ptr ds:[022A202Ch] 
00000040  mov         dword ptr [ebp-40h],eax 

        string test22 = test2;
00000043  mov         eax,dword ptr [ebp-40h] 
00000046  mov         dword ptr [ebp-44h],eax 

我使用“”,因為它會在我的代碼中明顯地變成黃色......出於某種原因,String.Empty在我的Visual Studio代碼主題中全是白色。 我相信這對我最重要。


我使用第三個,但其他兩個第一個似乎不太奇怪。 字符串是字符串的別名,但在分配中看到它們感覺不到。


我只是在看一些代碼,這個問題突然出現在我之前讀過的一些問題上。 這當然是一個可讀性問題。

考慮下面的C#代碼...

(customer == null) ? "" : customer.Name

VS

(customer == null) ? string.empty : customer.Name

我個人認為後者不太模糊,更易於閱讀。

正如其他人指出的那樣,實際差異可以忽略不計。


我在控制台應用程序中使用以下功能執行了這個非常簡單的測試

private static void CompareStringConstants()
{
    string str1 = "";
    string str2 = string.Empty;
    string str3 = String.Empty;
    Console.WriteLine(object.ReferenceEquals(str1, str2)); //prints True
    Console.WriteLine(object.ReferenceEquals(str2, str3)); //prints True
}

這清楚地表明,所有三個變量即str1str2str3雖然使用不同的語法進行了初始化,但卻指向了內存中完全相同的字符串(長度為零)。 我在.Net 4.5控制台應用程序中執行了此測試。 所以在內部他們沒有什麼區別,這一切都歸結為你想用作程序員的便利性。 字符串類的這種行為在.NET中稱為字符串實習 。 Eric Lippert here描述了這個概念。


我強烈喜歡String.Empty,除了其他原因以確保您知道它是什麼,並且您沒有意外刪除內容,但主要是為了國際化。 如果我在引號中看到一個字符串,那麼我總是想知道這是否是新代碼,應該將它放入一個字符串表中。 因此,每次代碼被更改/檢查時,您都需要查找“引用內容”,並且您可以過濾出空字符串,但我告訴人們最好不要將字符串放在引號中,除非您知道它不會被本地化。


我會贊成string.Empty over String.Empty因為您可以使用它而不需要包含using System; 在你的文件中。

至於選擇"" string.Empty ,這是個人喜好,應由你的團隊決定。


我親眼目睹了“”導致(次要)問題兩次。 一次是由於初級開發人員誤以團隊為基礎的編程,另一個是簡單的拼寫錯誤,但事實是使用string.Empty會避免這兩個問題。

是的,這是一個非常重要的判斷,但是當一種語言為你提供多種方式來做事時,我傾向於傾向於編譯器監督最多,編譯時間最強的那種語言。 那不是 “”。 這完全是為了表達特定的意圖。

如果你輸入string.EMpty或Strng.Empty,編譯器會讓你知道你做錯了。 立即。 它根本不會編譯。 作為開發人員,您正在引用編譯器(或其他開發人員)無法以任何方式誤解的具體意圖,並且當您做錯了時,您無法創建錯誤。

如果你的意思是“”,或者反之亦然,則鍵入“”,編譯器會愉快地做你告訴它做的事情。 另一個開發人員可能會或可能無法收集您的具體意圖。 Bug創建。

早在string.Empty之前,我用了一個定義EMPTY_STRING常量的標準庫。 我們仍然在不允許使用string.Empty的case語句中使用該常量。

只要有可能,就讓編譯器為你工作,並消除人為錯誤的可能性,無論多小。 海事組織,這與其他人所引用的一樣,勝過“可讀性”。

特定性和編譯時間執行。 這是吃晚飯的。


我認為第二個是“正確的”,但說實話我不認為這很重要。 編譯器應該足夠聰明,可以將其中任何一個編譯成完全相同的字節碼。 我使用“”我自己。


沒關係 - 他們完全一樣。 但主要的是你必須保持一致

我一直在與這種“什麼是正確的事情”鬥爭。


空字符串就像空集,只是一個名字,每個人都用它來調用"" 。 同樣在形式語言中,從字母表中創建長度為零的字符串稱為空字符串。 set和string都有一個特殊符號。 空字符串:ε和空集:∅。 如果你想談論這個零長度的字符串,你會稱它為空字符串,所以每個人都確切地知道你指的是什麼。 現在,如果您將其命名為空字符串,為什麼不在代碼中使用string.Empty ,則顯示其意圖是明確的。 缺點是它不是一個常數,因此無法在任何地方使用,如屬性。 (由於某些技術原因,這不是一個常數,請參閱參考資料。)


這個話題相當老舊,所以請原諒,如果這種行為已被其他地方提及。 (並指出我所涵蓋的答案)

如果使用string.Empty或雙引號,我發現編譯器的行為有所不同。 如果您不使用用string.Empty或雙引號初始化的字符串變量,那麼差異會顯示出來。

如果使用string.Empty進行初始化,則編譯器警告

CS0219 - The variable 'x' is assigned but its value is never used

絕不會在用雙引號初始化的情況下發出預期的消息。

此行為在此鏈接的“連接”文章中進行了解釋: https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value : https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value

基本上,如果我理解正確,他們希望允許程序員用函數的返回值設置一個變量用於調試目的,而不用打擾警告消息,因此它們僅在costant賦值和字符串的情況下限制警告。空不是一個常數,而是一個場。


這完全是一種代碼風格的偏好,請問.NET如何處理字符串。 但是,這裡是我的觀點:)

在訪問靜態方法,屬性和字段時,我始終使用BCL類型名稱: String.EmptyInt32.TryParse(...)Double.Epsilon

我在聲明新實例時總是使用C#關鍵字: int i = 0; 或者string foo = "bar";

我很少使用未聲明的字符串文字,因為我希望能夠掃描代碼以將它們組合成可重複使用的命名常量。 編譯器用常量替換常量,所以這更多地避免了魔術字符串/數字,並給它們一個更具有意義的名稱。 另外更改值更容易。





initialization