जवाबों:
संस्करण 2.0 से पहले .NET में, ""
ऑब्जेक्ट string.Empty
बनाता है जबकि नो ऑब्जेक्ट रेफरी बनाता है , जो string.Empty
अधिक कुशल बनाता है ।
संस्करण 2.0 और बाद में .NET में, सभी ""
स्ट्रिंग एक ही स्ट्रिंग शाब्दिक के संदर्भ में हैं, जिसका अर्थ ""
है कि यह समान है .Empty
, लेकिन फिर भी उतना तेज़ नहीं है .Length == 0
।
.Length == 0
सबसे तेज़ विकल्प है, लेकिन .Empty
थोड़ा क्लीनर कोड बनाता है।
string.IsNullOrEmpty( stringVar )
।
String.Empty और "" के बीच क्या अंतर है, और क्या वे विनिमेय हैं
string.Empty
एक केवल पढ़ने के लिए मैदान है, जबकि ""
एक संकलन समय स्थिर है। वे स्थान जहां वे अलग व्यवहार करते हैं:
C # 4.0 या उच्चतर में डिफ़ॉल्ट पैरामीटर मान
void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
//... implementation
}
स्विच स्टेटमेंट में केस एक्सप्रेशन
string str = "";
switch(str)
{
case string.Empty: // Error: A constant value is expected.
break;
case "":
break;
}
तर्क वितर्क करें
[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression
// or array creation expression of an attribute parameter type
String.Empty
ज्यादातर मामलों में एक तर्क के रूप में पारित कर सकते हैं । आप सही हैं कि सभी उदाहरण दिखाते हैं you simply can't put a (run-time) "value" into (compile-time) metadata
और वह वही है जो उदाहरण दिखाना चाहते हैं।
पिछले उत्तर .NET 1.1 के लिए सही थे (जिस पोस्ट को उन्होंने जोड़ा था उसकी तारीख देखें: 2003)। .NET 2.0 और बाद में, अनिवार्य रूप से कोई अंतर नहीं है। जेआईटी किसी भी तरह से ढेर पर उसी वस्तु को संदर्भित करेगा।
सी # विनिर्देश के अनुसार, खंड 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
प्रत्येक स्ट्रिंग शाब्दिक आवश्यक रूप से एक नए स्ट्रिंग उदाहरण में परिणाम नहीं करता है। जब दो या दो से अधिक स्ट्रिंग शाब्दिक स्ट्रिंग स्ट्रिंग ऑपरेटर (धारा 7.9.7) के अनुसार एक ही विधानसभा में दिखाई देते हैं, तो ये स्ट्रिंग शाब्दिक एक ही स्ट्रिंग उदाहरण को संदर्भित करते हैं।
ब्रैड अब्राम की पोस्ट की टिप्पणियों में भी किसी ने इसका उल्लेख किया है
सारांश में, "" बनाम स्ट्रिंग का व्यावहारिक परिणाम। खाली शून्य है। जेआईटी अंत में इसका पता लगाएगी।
मैंने पाया है, व्यक्तिगत रूप से, कि जेआईटी मेरे मुकाबले अधिक स्मार्ट है और इसलिए मैं कोशिश करता हूं कि इसके बाद माइक्रो-कंपाइलर अनुकूलन के साथ बहुत चालाक न हो। JIT () लूप्स के लिए प्रकट होगा, निरर्थक कोड, इनलाइन विधियों आदि को बेहतर तरीके से हटा देगा और अधिक उपयुक्त समय पर या तो I या C # कंपाइलर कभी भी हाथ से पहले अनुमान लगा सकता है। JIT को अपना काम करने दें :)
String.Empty
एक कॉन्स्टेबल फील्ड है, जबकि ""
एक कॉन्स्टेबल है । इसका मतलब है कि आप String.Empty
स्विच स्टेटमेंट में उपयोग नहीं कर सकते क्योंकि यह एक स्थिर नहीं है।
default
कीवर्ड के आगमन के साथ हम बिना पठनीयता को बढ़ावा दे सकते हैं, आकस्मिक संशोधन को रोक सकते हैं, और एक संकलन-समय स्थिर है, हालांकि ईमानदार होने के लिए, मुझे अभी भी लगता है कि
एक और अंतर यह है कि String.Empty बड़ा CIL कोड बनाता है। जबकि "" और स्ट्रिंग के संदर्भ के लिए कोड। String.Empty समान लंबाई है, स्ट्रिंग स्ट्रिंग के लिए कंपेन स्ट्रिंग स्ट्रिंग (एरिक लिपर्ट के ब्लॉग पोस्ट देखें ) का अनुकूलन नहीं करता है। खाली तर्क। निम्नलिखित समतुल्य कार्य
string foo()
{
return "foo" + "";
}
string bar()
{
return "bar" + string.Empty;
}
यह आईएल उत्पन्न करें
.method private hidebysig instance string foo() cil managed
{
.maxstack 8
L_0000: ldstr "foo"
L_0005: ret
}
.method private hidebysig instance string bar() cil managed
{
.maxstack 8
L_0000: ldstr "bar"
L_0005: ldsfld string [mscorlib]System.String::Empty
L_000a: call string [mscorlib]System.String::Concat(string, string)
L_000f: ret
}
"bar " + (ok ? "" : "error")
उपरोक्त उत्तर तकनीकी रूप से सही हैं, लेकिन आप वास्तव में क्या उपयोग करना चाहते हैं, सर्वोत्तम कोड पठनीयता के लिए और अपवाद का कम से कम मौका String.IsNullOrEmpty (s) है
--foo=$BAR
तो आप शायद उन दोनों के बीच अंतर को स्पॉट करना चाहते हैं जो एक एनवी var सेट करना भूल जाते हैं और वे ध्वज को बिल्कुल भी नहीं गुजारते हैं। string.IsNullOrEmpty
अक्सर एक कोड-गंध है जो आपने अपने इनपुट को ठीक से मान्य नहीं किया है या अजीब चीजें कर रहे हैं। जब आप वास्तव में उपयोग करने के लिए null
या शायद एक प्रकार / विकल्प प्रकार की तरह मतलब है , तो आपको आम तौर पर खाली तारों को स्वीकार नहीं करना चाहिए ।
मैं एक सरल के String.Empty
बजाय उपयोग करना चाहता हूं ""
, फिर भी स्पष्ट कारण नहीं है:
""
और""
न ही समान हैं, पहले वाले में वास्तव में 16 शून्य चौड़ाई वर्ण हैं। जाहिर है कि कोई भी सक्षम डेवलपर अपने कोड में चौड़ाई पात्रों को डालने और डालने वाला नहीं है, लेकिन अगर वे वहां पहुंचते हैं, तो यह एक रखरखाव दुःस्वप्न हो सकता है।
टिप्पणियाँ:
मैंने इस उदाहरण में U + FEFF का उपयोग किया ।
यकीन नहीं होता कि एसओ उन पात्रों को खाने जा रहा है, लेकिन कई शून्य-चौड़ाई वाले पात्रों में से एक के साथ खुद को आज़माएं
मैं केवल इस पर आया था https://codegolf.stackexchange.com/
के String.Empty
बजाय का उपयोग करें ""
।
यह मेमोरी उपयोग की तुलना में गति के लिए अधिक है लेकिन यह एक उपयोगी टिप है।
""
एक शाब्दिक तो एक शाब्दिक रूप में कार्य करेगा है: पहले उपयोग पर यह बनाई गई है और निम्न उपयोगों के लिए अपने संदर्भ दिया जाता है। केवल एक ही उदाहरण को""
मेमोरी में संग्रहीत किया जाएगा चाहे हम कितनी बार इसका उपयोग करें! मुझे यहाँ कोई स्मृति दंड नहीं दिखता है। समस्या यह है कि हर बार""
उपयोग किए जाने के बाद,""
आंतरिक पूल में पहले से ही है या नहीं , इसकी तुलना करने के लिए एक तुलना लूप निष्पादित किया जाता है। दूसरी तरफ, .NET फ्रेमवर्क मेमोरी ज़ोन में संग्रहीत केString.Empty
लिए एक संदर्भ है । ?""
String.Empty
VB.NET और C # एप्लिकेशन के लिए समान मेमोरी एड्रेस की ओर इशारा करता है। इसलिए""
जब आपको उस संदर्भ में आवश्यकता हो तो हर बार एक संदर्भ की खोज करेंString.Empty
संदर्भ: String.Empty
बनाम""
String.Empty एक ऑब्जेक्ट नहीं बनाता है जबकि "" करता है। हालांकि, जैसा कि यहां बताया गया है , अंतर, तुच्छ है।
"" के सभी उदाहरण समान हैं, इंटर्न स्ट्रिंग स्ट्रिंग शाब्दिक (या उन्हें होना चाहिए)। इसलिए आप वास्तव में हर बार आपके द्वारा उपयोग किए जाने वाले ढेर पर एक नई वस्तु नहीं फेंकेंगे "" लेकिन केवल उसी, आंतरिक वस्तु का संदर्भ बनाते हुए। ऐसा कहने के बाद, मैं स्ट्रिंग पसंद करता हूं। खाली। मुझे लगता है कि यह कोड को अधिक पठनीय बनाता है।
यह सिर्फ कोई फर्क नहीं पड़ता!
इसकी कुछ पिछली चर्चा:
http://www.codinghorror.com/blog/archives/000185.html
string mystring = "";
ldstr ""
ldstr
मेटाडेटा में संग्रहीत स्ट्रिंग शाब्दिक के लिए एक नया ऑब्जेक्ट संदर्भ धक्का देता है।
string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty
ldsfld
मूल्यांकन स्टैक पर स्थिर क्षेत्र का मान बढ़ाता है
मैं String.Empty
इसके बजाय उपयोग करना चाहता हूं ""
क्योंकि IMHO यह स्पष्ट और कम VB-ish है।
एरिक लिपर्ट ने लिखा (17 जून, 2013):
"सी एल्गोरिथ्म में मैंने जो पहला एल्गोरिथ्म कभी काम किया था, वह ऑप्टिमाइज़र था, जो स्ट्रिंग कॉन्टेनेनेशन को संभालता है। दुर्भाग्य से मैंने इसे छोड़ने से पहले रोसलिन कोडबेस को इन ऑप्टिमाइज़ेशन को पोर्ट करने का प्रबंधन नहीं किया; उम्मीद है कि कोई होगा उस के लिए जाओ! "
जनवरी 2019 तक कुछ रोसलिन x64 परिणाम यहां दिए गए हैं। इस पृष्ठ पर अन्य उत्तरों की सर्वसम्मति टिप्पणियों के बावजूद, यह मुझे नहीं दिखता है कि वर्तमान x64 JIT इन सभी मामलों को पहचानता है, जब सभी को कहा जाता है और किया जाता है।
विशेष रूप से ध्यान दें, हालांकि, इनमें से केवल एक उदाहरण वास्तव में कॉलिंग को समाप्त करता है String.Concat
, और मैं अनुमान लगा रहा हूं कि यह अस्पष्टता शुद्धता कारणों के लिए है (जैसा कि एक अनुकूलन निरीक्षण के विपरीत)। अन्य अंतर समझाने में कठिन लगते हैं।
डिफ़ॉल्ट (स्ट्रिंग) + {डिफ़ॉल्ट (स्ट्रिंग), "", String.Empty}
static String s00() => default(String) + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s01() => default(String) + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s02() => default(String) + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
"" + {डिफ़ॉल्ट (स्ट्रिंग), "", String.Empty}
static String s03() => "" + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s04() => "" + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s05() => "" + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
String.Empty + {default (स्ट्रिंग), "", String.Empty}
static String s06() => String.Empty + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s07() => String.Empty + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s08() => String.Empty + String.Empty;
mov rcx,[String::Empty]
mov rcx,qword ptr [rcx]
mov qword ptr [rsp+20h],rcx
mov rcx,qword ptr [rsp+20h]
mov rdx,qword ptr [rsp+20h]
call F330CF60 ; <-- String.Concat
nop
add rsp,28h
ret
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
AMD64 Release
[MethodImpl(MethodImplOptions.NoInlining)]
'SuppressJitOptimization' = false
एंटिटी फ्रेमवर्क के दृष्टिकोण से इस पर आ रहा है: EF संस्करण 6.1.3 स्ट्रींग का इलाज करता है। खाली और मान्य होने पर "" अलग तरीके से।
string.Empty को सत्यापन के प्रयोजनों के लिए एक शून्य मान के रूप में माना जाता है और यदि यह आवश्यक (आरोपित) फ़ील्ड पर उपयोग किया जाता है तो सत्यापन त्रुटि को फेंक देगा; जहां "" सत्यापन मान्य होगा और त्रुटि को नहीं फेंकेगा।
यह समस्या EF 7+ में हल हो सकती है। संदर्भ: - https://github.com/aspnet/EntityFramework/issues/2610 )।
संपादित करें: [आवश्यक (AllowEmptyStrings = true)] इस समस्या को हल करेगा, स्ट्रिंग को अनुमति देने के लिए।
चूंकि String.Empty एक संकलन-समय स्थिर नहीं है, इसलिए आप इसे फ़ंक्शन परिभाषा में डिफ़ॉल्ट मान के रूप में उपयोग नहीं कर सकते।
public void test(int i=0,string s="")
{
// Function Body
}
public void test(int i=0, string s=string.Empty) {}
संकलित नहीं करेंगे और कहेंगे कि "s 'के लिए डिफ़ॉल्ट पैरामीटर मान एक संकलन-समय स्थिर होना चाहिए। OP का उत्तर काम करता है।
जब आप कोड के माध्यम से नेत्रहीन स्कैनिंग कर रहे हैं, तो "" जिस तरह से तार रंगे हुए हैं, उसे रंगा हुआ दिखाई देता है। string.Empty एक नियमित वर्ग-सदस्य-पहुंच की तरह दिखता है। एक त्वरित नज़र के दौरान, इसका आसान स्थान "" या अर्थ को अंतर करना।
स्ट्रिंग्स को स्पॉट करें (स्टैक ओवरफ्लो कलराइजेशन बिल्कुल मदद नहीं कर रहा है, लेकिन वीएस में यह अधिक स्पष्ट है):
var i = 30;
var f = Math.Pi;
var s = "";
var d = 22.2m;
var t = "I am some text";
var e = string.Empty;
\u00ad
।
यहां हर कोई कुछ अच्छा सैद्धांतिक स्पष्टीकरण देता है। मुझे भी ऐसा ही संदेह था। इसलिए मैंने इस पर एक बुनियादी कोडिंग की कोशिश की। और मैंने एक अंतर पाया। यहाँ अंतर है।
string str=null;
Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference.
string str = string.Empty;
Console.WriteLine(str.Length); // 0
तो ऐसा लगता है कि "नल" का मतलब बिल्कुल शून्य है और "स्ट्रिंग। खाली" का मतलब है कि इसमें किसी प्रकार का मूल्य है, लेकिन यह खाली है।
""
बनाम के बारे में है string.Empty
। केवल यह बताने की कोशिश की जा रही है कि क्या स्ट्रिंग खाली है, null
इसका उल्लेख किया गया था।
string.Empty
था औरreadonly
इसके बजाय इसे घोषित करने के पीछे तर्क क्या थाconst
।