[英]In C#, should I use string.Empty or String.Empty or "" to intitialize a string?
在C#中,我想用一個空字符串初始化一個字符串值。
我應該怎么做? 什么是正確的方法,為什么?
string willi = string.Empty;
要么
string willi = String.Empty;
要么
string willi = "";
或者是什么?
使用您和您的團隊認為最具可讀性的任何內容。
其他答案建議每次使用""
時都會創建一個新字符串。 這不是真的 - 由於字符串實習,它將在每個程序集或每個 AppDomain 中創建一次(或者可能在整個過程中創建一次 - 在這方面不確定)。 這種差異可以忽略不計-大規模,大量微不足道。
但是,您發現哪個更具可讀性是另一回事。 這是主觀的,會因人而異——所以我建議你找出你團隊中大多數人喜歡什么,然后為了一致性而一致。 我個人覺得""
更容易閱讀。
""
和" "
很容易被誤認為是彼此的論點並沒有真正讓我感到滿意。 除非您使用的是比例字體(我還沒有與任何這樣做的開發人員合作過),否則很容易區分。
從性能和代碼生成的角度來看,確實沒有區別。 在性能測試中,他們在哪個更快與另一個之間來回切換,並且僅相差幾毫秒。
在查看幕后代碼時,您也確實看不出任何區別。 唯一的區別是在 IL 中,其中string.Empty
使用操作碼ldsfld
而""
使用操作碼ldstr
,但這只是因為string.Empty
是靜態的,並且兩個指令都執行相同的操作。 如果您查看生產的組件,它是完全相同的。
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
.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
或String.Empty
更喜歡""
。 這兩個長六倍,沒有額外的好處——當然沒有增加清晰度,因為它們表達了完全相同的信息。
一個區別是,如果您使用switch-case
語法,則不能編寫case string.Empty:
因為它不是常量。 你得到一個Compilation error : A constant value is expected
查看此鏈接了解更多信息: string-empty-versus-empty-quotes
我更喜歡string
而不是String
。 選擇string.Empty
不是""
是選擇一個並堅持下去的問題。 使用string.Empty
優點是您的意思非常明顯,並且您不會意外地復制"\\x003"
中的""
"\\x003"
等不可打印字符。
我不打算插話,但我看到一些錯誤的信息在這里被拋出。
我個人更喜歡string.Empty
。 這是個人偏好,我會根據具體情況服從與我合作的任何團隊的意願。
正如其他一些人所提到的, string.Empty
和String.Empty
之間根本沒有區別。
此外,這是一個鮮為人知的事實,使用 "" 是完全可以接受的。 在其他環境中,"" 的每個實例都會創建一個對象。 但是,.NET 實習其字符串,因此未來的實例將從實習池中提取相同的不可變字符串,並且任何性能損失都可以忽略不計。 資料來源:布拉德艾布拉姆斯。
我個人更喜歡 "" 除非有充分的理由來處理更復雜的事情。
String.Empty
和string.Empty
是等價的。 String
是 BCL 類名; string
是它的 C# 別名(或快捷方式,如果你願意的話)。 與Int32
和int
相同。 有關更多示例,請參閱文檔。
至於""
,我不太確定。
就個人而言,我總是使用string.Empty
。
我在控制台應用程序中使用以下方法執行了這個非常簡單的測試:
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
}
這清楚地表明,所有三個變量,即str1
、 str2
和str3
盡管使用不同的語法初始化,但都指向內存中完全相同的字符串(零長度)對象。 我在 .NET 4.5 控制台應用程序中執行了這個測試。 所以在內部它們沒有區別,這一切都歸結為您想作為程序員使用哪一個的便利性。 字符串類的這種行為在 .NET 中稱為字符串實習。 Eric Lippert 有一個非常好的博客在這里描述了這個概念。
幾乎每個開發人員都知道“”是什么意思。 我個人第一次遇到 String.Empty 並且不得不花一些時間在 google 上搜索以確定它們是否真的是完全相同的東西。
這個話題很老而且很長,所以如果在其他地方提到了這種行為,請原諒。 (並指出我的答案,涵蓋了這一點)
如果您使用string.Empty
或雙引號,我發現編譯器的行為會有所不同。 如果您不使用用 string.Empty 或雙引號初始化的字符串變量,差異就會顯現出來。
如果使用string.Empty
初始化,則編譯器警告
CS0219 - The variable 'x' is assigned but its value is never used
永遠不會發出,而在使用雙引號初始化的情況下,您會得到預期的消息。
此行為在此鏈接的 Connect 文章中進行了解釋: https : //connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value
基本上,如果我做對了,他們希望允許程序員設置一個帶有函數返回值的變量以用於調試目的,而不會用警告消息打擾他,因此他們只在持續賦值和字符串的情況下限制了警告。 Empty 不是常量而是一個字段。
沒有人提到在 VisualStudio 中字符串的顏色編碼與字符串不同。 這對可讀性很重要。 此外,小寫通常用於 vars 和 type,沒什么大不了的,但 String.Empty 是一個常量而不是 var 或類型。
以上任何一項。
有很多很多更好的事情需要宣揚。 比如什么顏色的樹皮最適合樹,我認為是帶有淡淡苔蘚的模糊棕色。
我非常喜歡 String.Empty,除了確保您知道它是什么以及您沒有意外刪除內容的其他原因之外,主要是為了國際化。 如果我在引號中看到一個字符串,那么我總是想知道這是否是新代碼,是否應該將其放入字符串表中。 因此,每次更改/審查代碼時,您都需要查找“引號中的內容”,是的,您可以過濾掉空字符串,但我告訴人們最好不要將字符串放在引號中,除非您知道它不會被本地化.
string
是System.String
類型的同義詞,它們是相同的。
值也相同: string.Empty == String.Empty == ""
我不會在代碼中使用字符常量 "",而是使用string.Empty
或String.Empty
- 更容易理解程序員的意思。
在string
和String
之間,我更喜歡小寫string
,因為我曾經使用 Delphi 工作了很多年,而 Delphi 風格是小寫string
。
所以,如果我是你的老板,你會寫string.Empty
我更喜歡string.Empty
不是String.Empty
因為你可以使用它而無需包含using System;
在您的文件中。
至於選擇""
不是string.Empty
,這是個人喜好,應該由您的團隊決定。
我沒有任何區別。 最后一個是最快的輸入:)
這完全是一種代碼風格的偏好,是關於 .NET 如何處理字符串的。 但是,這是我的意見:)
在訪問靜態方法、屬性和字段時,我總是使用 BCL 類型名稱: String.Empty
或Int32.TryParse(...)
或Double.Epsilon
我在聲明新實例時總是使用 C# 關鍵字: int i = 0;
或string foo = "bar";
我很少使用未聲明的字符串文字,因為我喜歡能夠掃描代碼將它們組合成可重用的命名常量。 編譯器無論如何都會用文字替換常量,因此這更像是一種避免魔術字符串/數字並通過名稱賦予它們更多含義的方法。 此外,更改值更容易。
沒關系 - 它們是完全一樣的。 然而,最重要的是你必須保持一致
ps我一直在為這種“什么是正確的事情”而掙扎。
我親眼目睹了兩次導致(小)問題的“”。 一次是由於初級開發人員對基於團隊的編程不熟悉,另一個是簡單的錯字,但事實是使用 string.Empty 可以避免這兩個問題。
是的,這在很大程度上是一種判斷,但是當一種語言為您提供多種做事方式時,我傾向於傾向於具有最多編譯器監督和最強編譯時強制執行的語言。 那不是“”。 一切都是為了表達特定的意圖。
如果您鍵入 string.EMpty 或 Strng.Empty,編譯器會讓您知道您做錯了。 立即地。 它根本不會編譯。 作為開發人員,您引用了編譯器(或其他開發人員)不能以任何方式誤解的特定意圖,並且當您做錯時,您無法創建錯誤。
如果您在表示“”時鍵入“”,反之亦然,編譯器會很高興地按照您的要求執行。 其他開發人員可能會也可能不會收集您的特定意圖。 錯誤創建。
早在 string.Empty 之前,我就使用了定義 EMPTY_STRING 常量的標准庫。 我們仍然在不允許 string.Empty 的 case 語句中使用該常量。
只要有可能,就讓編譯器為您工作,並消除人為錯誤的可能性,無論多么小。 IMO,正如其他人所引用的那樣,這勝過“可讀性”。
特異性和編譯時強制執行。 這是晚餐吃的。
我使用第三個,但在其他兩個中,第一個似乎不那么奇怪。 string 是 String 的別名,但是在作業中看到它們感覺很不舒服。
前兩者中的任何一個對我來說都是可以接受的。 我會避免使用最后一個,因為通過在引號之間放置一個空格來引入錯誤相對容易。 通過觀察很難發現這個特定的錯誤。 假設沒有錯別字,所有在語義上都是等價的。
[編輯]
此外,您可能希望始終使用string
或String
以保持一致性,但這只是我。
我使用 "" 是因為它在我的代碼中會被着色成明顯的黃色......出於某種原因,String.Empty 在我的 Visual Studio Code 主題中全是白色的。 我相信這對我來說是最重要的。
從長遠來看,編譯器應該使它們完全相同。 選擇一個標准,以便您的代碼易於閱讀,並堅持下去。
我只是在看一些代碼,這個問題突然出現在我的腦海中,我之前看過這個問題。 這當然是可讀性的問題。
考慮以下 C# 代碼...
(customer == null) ? "" : customer.Name
對比
(customer == null) ? string.empty : customer.Name
我個人認為后者不那么模棱兩可,更容易閱讀。
正如其他人所指出的,實際差異可以忽略不計。
我認為第二個是“適當的”,但老實說,我認為這無關緊要。 編譯器應該足夠聰明,可以將其中任何一個編譯為完全相同的字節碼。 我自己用“”。
雖然差異非常非常小,但差異仍然存在。
1) "" 創建對象,而 String.Empty 不會。 但是這個對象將被創建一次,如果代碼中有另一個“”,稍后將從字符串池中引用。
2) String 和 string 相同,但我建議使用 String.Empty(以及 String.Format、String.Copy 等),因為點符號表示類,而不是運算符,並且類以大寫字母開頭符合C# 編碼標准。
空字符串就像空集,只是每個人都用來稱呼""
。 同樣在正式語言中,由長度為零的字母表創建的字符串稱為空字符串。 set 和 string 都有一個特殊的符號。 空串:ε 和空集:∅。 如果你想談論這個零長度的字符串,你會稱它為空字符串,這樣每個人都知道你指的是什么。 現在,如果您將其命名為空字符串,為什么不在代碼中使用string.Empty
,它的意圖是明確的。 缺點是它不是一個常數,因此在任何地方都不可用,就像在屬性中一樣。 (由於某些技術原因,它不是常數,請參閱參考資料。)
在http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx 上:
正如大衛所暗示的那樣,
String.Empty
和""
之間的差異非常小,但還是有區別的。""
實際上創建了一個對象,它可能會被從字符串實習池中拉出,但仍然......而String.Empty
創建任何對象......所以如果你真的在尋找最終的內存效率,我建議使用String.Empty
。 但是,您應該記住,差異是如此微不足道,您可能永遠不會在代碼中看到它......
至於System.String.Empty
或string.Empty
或String.Empty
......我的護理水平很低;-)
我更喜歡""
因為它更短,並且String.Empty
解決了不存在的問題。
可能是一個有爭議的評論,但總的來說,我發現當我與 Microsoft 一致行動時,我的生活會更輕松。 我們不可能知道他們做事的全部深層原因(有時非常嚴格,有時我認為有時很笨拙)。
他們在諸如程序集文件之類的自動生成的文件中使用“”,這就是我所做的。 事實上,當我嘗試用 String.Empty 替換“”下面的任何內容時,Visual Studio 會崩潰。 對此可能有一個合乎邏輯的解釋,但以我有限的知識,如果我只是按照他們所做的去做,大多數情況下,事情都會解決。 (相反:我知道他們一些自動生成的文件也使用 String.Empty,這打破了我的觀點。:))
<Assembly: System.Reflection.AssemblyCulture("")>
<Assembly: System.Reflection.AssemblyDescription("")>
<Assembly: System.Reflection.AssemblyFileVersion("1.0.0.0")>
<Assembly: System.Reflection.AssemblyKeyFile("")>
<Assembly: System.Reflection.AssemblyProduct("")>
<Assembly: System.Reflection.AssemblyTitle("")>
如果您想惡作劇某人,請將""
放入他們的代碼中。 這不是空字符串,它是""
。 你不能用string.Empty
來愚弄別人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.