वैकल्पिक पैरामीटर के लिए डिफ़ॉल्ट मान के रूप में स्ट्रिंग का उपयोग नहीं किया जा सकता


89

मैं बिल वैगनर द्वारा इफेक्टिव सी # पढ़ रहा हूं । में आइटम 14 - कम से कम डुप्लिकेट प्रारंभ तर्क है, वह नई वैकल्पिक पैरामीटर एक निर्माता में शामिल का उपयोग करने का निम्न उदाहरण दिखाता है:

public MyClass(int initialCount = 0, string name = "")

ध्यान दें कि वह ""इसके बजाय इस्तेमाल किया string.Empty
वह टिप्पणी करता है:

आप [ऊपर के उदाहरण में] नोट करेंगे कि दूसरा निर्माता निर्दिष्ट नाम के बजाय डिफ़ॉल्ट पैरामीटर के लिए "" अधिक प्रथागत है string.Empty। ऐसा इसलिए string.Emptyहै क्योंकि एक संकलन-समय स्थिर नहीं है। यह स्ट्रिंग क्लास में परिभाषित एक स्थिर संपत्ति है। क्योंकि यह एक संकलित स्थिरांक नहीं है, आप इसे किसी पैरामीटर के लिए डिफ़ॉल्ट मान के लिए उपयोग नहीं कर सकते।

यदि हम string.Emptyसभी स्थितियों में स्थैतिक का उपयोग नहीं कर सकते हैं , तो क्या इसका उद्देश्य नहीं है? मैंने सोचा था कि हम इसका उपयोग यह सुनिश्चित करने के लिए करेंगे कि हमारे पास खाली स्ट्रिंग को संदर्भित करने के लिए एक प्रणाली-स्वतंत्र साधन है। क्या मेरी समझ गलत है? धन्यवाद।

अद्यतन
केवल एक अनुवर्ती टिप्पणी। MSDN के अनुसार:

प्रत्येक वैकल्पिक पैरामीटर में इसकी परिभाषा के भाग के रूप में एक डिफ़ॉल्ट मान होता है। यदि उस पैरामीटर के लिए कोई तर्क नहीं भेजा जाता है, तो डिफ़ॉल्ट मान का उपयोग किया जाता है। डिफ़ॉल्ट मान स्थिरांक होना चाहिए।

तब हम System.Environment.NewLineया तो उपयोग नहीं कर सकते हैं या डिफ़ॉल्ट रूप में नए तात्कालिक वस्तुओं का उपयोग कर सकते हैं। मैंने अभी तक VS2010 का उपयोग नहीं किया है, और यह निराशाजनक है!


2
विभिन्न प्लेटफार्मों पर खाली तारों का प्रतिनिधित्व कैसे किया जाता है, इसके बीच कोई अंतर नहीं है। यह न्यूलाइन की तरह नहीं है।
टॉम कैबांस्की

ठीक है, मैं सोच रहा था कि, तो क्या यह सिर्फ यह है कि यह कोड में अच्छा लग रहा है?
मिकीगिह

1
सीएलआर और न कि 'सिस्टम' यह निर्धारित करने वाला कारक है कि "" एक रिक्त स्ट्रिंग है या नहीं। इसलिए मुझे लगता है कि आप सुरक्षित रूप से यह मान सकते हैं कि "" एक अनिवार्य सीएलआर कार्यान्वयन पर एक स्ट्रिंग को संदर्भित करने का एक स्वतंत्र तरीका है।
क्रिस टेलर

"प्रणाली स्वतंत्र"? एर, सिस्टम-विशिष्ट "" के विपरीत? (???)
Qwertie

MSDN के अनुसार: इस फ़ील्ड का मान शून्य-लंबाई वाला स्ट्रिंग है, ""। तो यह स्पष्ट रूप से मंच की स्वतंत्रता से कोई लेना-देना नहीं है, जैसा कि कई लोग इशारा कर रहे हैं। फिर भी यह अभी भी लगता है कि लोग वास्तव में नहीं जानते हैं कि इसका उपयोग क्यों किया जाना चाहिए!
मिकीगिह

जवाबों:


65

C # 2.0 कंपाइलर के रूप में, String.Emptyवैसे भी बहुत कम बिंदु है , और वास्तव में कई मामलों में यह एक निराशा है, क्योंकि कंपाइलर कुछ संदर्भों को इनलाइन ""कर सकता है, लेकिन इसके साथ ऐसा नहीं कर सकता है String.Empty

C # 1.1 में यह बहुत सारी स्वतंत्र वस्तुओं को बनाने से बचने के लिए उपयोगी था जिसमें सभी खाली स्ट्रिंग होते हैं, लेकिन वे दिन चले गए हैं। ""ठीक काम करता है।


7
.NET 1.1 में भी यह स्वतंत्र वस्तुओं का "लॉट" नहीं बनाएगा। मुझे इस संबंध में 1.1 और 2.0 के बीच के अंतरों का विवरण याद नहीं है, लेकिन यह ऐसा नहीं है जैसे कि स्ट्रिंग शाब्दिक इंटर्निंग केवल 2.0 में शुरू की गई थी।
जॉन स्कीट

स्पष्टीकरण के लिए धन्यवाद। मैं चारों ओर देख चुका हूँ और मुझे C # 2.0 में परिवर्तनों का अच्छा सारांश नहीं मिला है, हालाँकि मुझे यकीन है कि मैंने एक बार पढ़ा है। मुझे कुछ तकनीकी जानकारी के लिंक के साथ 2008 से स्टैकऑवरफ्लो उत्तर मिला। stackoverflow.com/questions/151472/…
एंडी मोर्टिमर

1
मैं इसे एक संकेत दूंगा, हालांकि मुझे यह कहना पसंद नहीं है कि स्ट्रिंग के लिए बहुत कम बिंदु हैं। खाली करें क्योंकि मैं इसका काफी उपयोग करता हूं। मुझे लगता है कि यह सिर्फ साफ दिखता है, हालांकि यह मेरी निजी राय है। कई जगह स्ट्रिंग हैं। खाली उपयोग नहीं किया जा सकता है, और मुझे उन मामलों में "" का उपयोग करने में कोई समस्या नहीं है
xximjasonxx

14
मैंने पाया है कि स्ट्रिंग के साथ एक खाली स्ट्रिंग को जल्दी से पहचानना बहुत आसान है। यह सुनिश्चित करने के लिए "" में दो बार देखने से खाली है कि इसमें एक एपॉस्ट्रॉफ़ या ऐसा कुछ नहीं है जो इसमें छिपा हुआ है। हालांकि स्पष्टीकरण के लिए +1।
21

11
+1 क्रिस। वीएस में भी, आप वास्तव में "" के मानक पर खोज नहीं कर सकते हैं (मानक खोजें करने के अलावा जो प्रत्येक पाठ मैच को वापस लाएगा, जिसमें टिप्पणियां और मार्कअप भी शामिल हैं)। आप string.Empty के साथ कोड विशिष्ट उपयोगों पर एक खोज कर सकते हैं।
MutantNinjaCodeMonkey

53

यदि आप वास्तव में इसे वैकल्पिक पैरामीटर मान के रूप में उपयोग करना चाहते हैं, तो आपको खाली स्ट्रिंग के लिए अपने स्वयं के निरंतर को परिभाषित करने से रोकने के लिए कुछ भी नहीं है:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[एक तरफ के रूप में, सामान्य रूप String.Emptyसे अधिक पसंद करने का एक कारण "", जिसका उल्लेख अन्य उत्तरों में नहीं किया गया है, यह है कि विभिन्न यूनिकोड वर्ण (शून्य-चौड़ाई वाले योजक, आदि) हैं जो प्रभावी रूप से नग्न आंखों के लिए अदृश्य हैं। तो कुछ ऐसा दिखता है जो ""जरूरी नहीं कि खाली स्ट्रिंग है, जबकि String.Emptyआप जानते हैं कि आप क्या उपयोग कर रहे हैं। मैं मानता हूं कि यह बग का सामान्य स्रोत नहीं है, लेकिन यह संभव है।]


2
अदृश्य पहचानकर्ता वर्ण भी हैं, इसलिए ऐसा कुछ जो String_Empty जैसा दिखता है जरूरी नहीं है। यूनिकोड मानक में सुरक्षा विचारों पर एक बड़े पैमाने पर अनदेखा अध्याय है।
जिम बाल्टर

25

मूल प्रश्न से:

मैंने सोचा था कि हम इसका उपयोग यह सुनिश्चित करने के लिए करेंगे कि हमारे पास खाली स्ट्रिंग को संदर्भित करने के लिए एक प्रणाली-स्वतंत्र साधन है।

किस तरह से खाली स्ट्रिंग सिस्टम से सिस्टम में भिन्न हो सकती है? यह हमेशा कोई अक्षर नहीं है! मैं वास्तव में डर जाता हूँ अगर मुझे कभी एक कार्यान्वयन मिला जहाँ string.Empty == ""झूठे लौटे :) यह कुछ ऐसा ही नहीं है Environment.NewLine

काउंटर टेररिस्ट की बाउंटी पोस्ट से:

मैं चाहता हूं कि String.Empty का उपयोग अगले C # रिलीज़ में एक डिफ़ॉल्ट पैरामीटर के रूप में किया जा सकता है। : डी

खैर यह निश्चित रूप से नहीं होने जा रहा है।

जबकि मैं व्यक्तिगत रूप से एक बहुत अलग डिफ़ॉल्ट तंत्र को पसंद करूंगा, जिस तरह से वैकल्पिक पैरामीटर काम शुरू से ही .NET में है - और इसका हमेशा मतलब है कि मेटाडेटा में एक स्थिरांक को एम्बेड करना, ताकि कॉलिंग कोड कॉल में उस निरंतर को कॉपी कर सके। साइट यदि कोई संगत तर्क प्रदान नहीं किया गया है।

इसके साथ string.Emptyयह वास्तव में व्यर्थ है - ""आप जो चाहते हैं उसका उपयोग करेंगे; यह है कि स्ट्रिंग शाब्दिक का उपयोग करने के लिए दर्दनाक है? (मैं हर जगह शाब्दिक का उपयोग करता हूं - मैं कभी भी उपयोग नहीं करता string.Empty- लेकिन यह एक अलग तर्क है।)

इस सवाल के बारे में मुझे आश्चर्य है - शिकायत कुछ ऐसी चीज के इर्द-गिर्द घूमती है, जो वास्तव में वास्तविक समस्या का कारण नहीं बनती। यह उन मामलों में अधिक महत्वपूर्ण है, जहां आप चाहते हैं कि निष्पादन समय पर डिफ़ॉल्ट की गणना की जाए क्योंकि यह वास्तव में भिन्न हो सकता है। उदाहरण के लिए, मैं उन मामलों की कल्पना कर सकता हूं जहां आप किसी DateTimeपैरामीटर के साथ एक विधि को कॉल करने में सक्षम होना चाहते हैं और यह "वर्तमान समय" के लिए डिफ़ॉल्ट है। इस समय, केवल बेहद सुरुचिपूर्ण वर्कअराउंड जो मुझे पता है, वह है:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... लेकिन यह हमेशा उचित नहीं है।

निष्कर्ष के तौर पर:

  • मुझे बहुत संदेह है कि यह कभी C # का हिस्सा होगा
  • इसके लिए string.Emptyवैसे भी व्यर्थ है
  • के लिए अन्य मान जो वास्तव में नहीं है हमेशा एक ही मूल्य है, यह वास्तव में कर सकते हैं एक दर्द हो सकता है

यह वास्तव में समस्या को ठीक करने का एक अच्छा तरीका है। एक ही चीज़ का उपयोग अन्य डिवाइस पर निर्भर चर को ले जाने / सेट करने के लिए किया जा सकता है, जैसे Environment.Newline.. आपके उदाहरण से गायब होने वाली एकमात्र चीज़ अशक्त के लिए चर पर एक जाँच होगी, और एक अपवाद को वापस फेंकते हुए डेवलपर को यह बताते हुए कि वह अशक्त है, यह मंजूर नहीं। if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");}या कुछ इस तरह का। लेकिन मुझे वास्तव में यह पसंद है! किसी भी अन्य तरीके से इसे अपने तरीके से करने के लिए?
मैक्सवद्रव

@MaxOvrdrv: आप यह नहीं चाहते हैं कि यह एक त्रुटि के रूप में शून्य है - पूरे बिंदु यह है कि जब यह शून्य है, तो आप एक डिफ़ॉल्ट की गणना करते हैं। चेतावनी यह है कि यह शून्य को अपने आप में एक वैध मूल्य के रूप में पारित करने की अनुमति नहीं देता है।
जॉन स्कीट

आप इसके बारे में पूरी तरह से सही हैं। मेरी गलती। - और हाँ, यह केवल वास्तविक चेतावनी होगी ... यह बहुत बुरा नहीं है। फिर: मैं वास्तव में इस समाधान की तरह! :) इसे पोस्ट करने के लिए धन्यवाद! :)
मैक्सवोर्द्रव

7

मैं स्ट्रिंग का उपयोग कभी नहीं करता हूं। खाली, मैं इसके बारे में नहीं देख सकता। शायद यह उन लोगों के लिए आसान बनाता है जो वास्तव में प्रोग्रामिंग के लिए नए हैं, लेकिन मुझे संदेह है कि यह उसके लिए भी उपयोगी है।


2
शायद यह भ्रमित करने से रोकता है ""और " ", लेकिन मैं यह नहीं कह सकता कि " "यह सब आम है।
ग्रेग

8
मेरा सुझाव है कि जो कोई भी उन जरूरतों के बीच अंतर को बेहतर चश्मा नहीं बता सकता है या अपनी स्क्रीन के रिज़ॉल्यूशन को कम कर सकता है। मुझे बुरी नज़र लग गई है और मैं कभी भी उस गलती को याद नहीं कर सकता (और मुझे बहुत सारे कोड के साथ काम करना होगा जिसमें दोनों शामिल हैं)।
हंस ओलसन

2
string.Empty प्रोग्रामर के सटीक इरादे का पता लगाने के लिए उपयोगी है। "" इरादे के बारे में कुछ भी नहीं बताता है, क्या होगा यदि प्रोग्रामर का इरादा इस "लोल" जैसे चर को शुरू करना था, लेकिन भूल गया ... इस मामले में अंतहीन संभावनाएं और स्ट्रिंग हैं, खाली आता है और एक बेहतर काम करता है
उपयोगी

4

मुझे लगता है कि स्ट्रिंग के पीछे का विचार। खाली है कि यह पठनीयता को बढ़ाता है। यह न्यूलाइन की तरह नहीं है जहां विभिन्न प्लेटफार्मों पर इसका प्रतिनिधित्व कैसे किया जाता है, इसके बीच कोई अंतर है। यह शर्म की बात है कि यह एक डिफ़ॉल्ट पैरामीटर में उपयोग नहीं किया जा सकता है। हालाँकि, यह किसी भी समस्या का कारण नहीं होगा यदि आप विंडोज और लिनक्स पर मोनो जैसे कुछ के बीच पोर्ट करते हैं।


5
मुझे लगता है कि आप शायद सही हैं कि बात यह है कि कुछ लोग String.Emptyअधिक पठनीय मानते हैं । । । हालांकि, मुझे लगता है कि यह थोड़ा अखरोट है। ""शायद वहाँ सबसे आम स्ट्रिंग है और सभी ने इसे एक अरब बार देखा है, तो यह कैसे अपठनीय है? String.Emptyके बारे में के रूप में उपयोगी है अगर वहाँ एक थे Int32.Zero
टिम गुडमैन

3

एक FYI के रूप में, ऐसा लगता है कि समान अवरोधक निर्माण निर्माताओं को दिए गए मूल्यों पर लगाए गए हैं - उन्हें निरंतर होना चाहिए। चूंकि string.empty परिभाषित किया गया है:

public static readonly string Empty

वास्तविक स्थिरांक की बजाय इसका उपयोग नहीं किया जा सकता है।


1

मैं string.Emptyविशुद्ध रूप से पठनीयता के लिए उपयोग करता हूं ।

अगर किसी और को मेरे कोड को पढ़ने / बदलने की आवश्यकता है, तो बाद में उन्हें पता चलता है कि मेरा मतलब खाली स्ट्रिंग के लिए कुछ जांचना या सेट करना है। बस का उपयोग करना ""कभी-कभी बग और भ्रम का कारण बन सकता है क्योंकि मैं अभी उस स्ट्रिंग को डालना भूल गया हूं जो मैं चाहता था।

उदाहरण के लिए:

if(someString == string.Empty)
{

}

बनाम

if(someString == "")
{

}

पहला ifबयान मुझे इतना अधिक जानबूझकर और पठनीय लगता है। क्योंकि यह सिर्फ एक प्राथमिकता है, हालांकि, मैं वास्तव में ""इसके बजाय उपयोग करने के लिए ट्रेन-स्मैश नहीं देखता हूं string.Empty


-2

शायद इस समस्या का सबसे अच्छा समाधान इस पद्धति का एक अधिभार है, इस तरह से:

public static void PrintString() 
{ 
    PrintString(string.Empty);
}

3
उपरोक्त प्रश्न का उत्तर कैसे है?
प्रणव सिंह

1
यह वैकल्पिक मापदंडों के लिए डिफ़ॉल्ट मानों के साथ कैसे मदद करता है?
डिफ़ॉल्ट लोकेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.