Null-Coalescing Operator के साथ Null ऑब्जेक्ट्स को इंस्टेंट करना


12

निम्नलिखित विशिष्ट परिदृश्य पर विचार करें:

if(myObject == null) {
    myObject = new myClass();
}

मैं सोच रहा हूं कि अशक्त-सहवर्ती ऑपरेटर का उपयोग करके निम्नलिखित प्रतिस्थापन के बारे में क्या सोचा गया है:

myObject = myObject ?? new myClass();

मुझे यकीन नहीं है कि मुझे दूसरे फॉर्म का उपयोग करना चाहिए या नहीं। यह एक अच्छा शॉर्टहैंड की तरह लगता है, लेकिन myObject = myObjectशुरुआत में निर्माण ऐसा लगता है जैसे यह कोड-गंध का एक सा हो सकता है।

क्या यह एक उचित बात है, या क्या कोई बेहतर शॉर्टहैंड है जो मुझे याद आ रही है? या हो सकता है, "यह तीन लाइनें हैं, इसे खत्म कर दो!"

संपादित करें: जैसा कि उल्लेख किया गया है, शायद यह एक विशिष्ट परिदृश्य कह रहा है एक अतिरंजना का कुछ है। मुझे आमतौर पर लगता है कि मैं इस स्थिति का सामना कर रहा हूं जब मैं एक डेटाबेस से एक इकाई प्राप्त कर रहा हूं जिसमें एक बच्चा संदर्भ प्रकार की संपत्ति है जो अभी तक पॉपुलर नहीं हो सकती है:

myClass myObject = myClassService.getById(id);
myObject.myChildObject = myObject.myChildObject ?? new myChildClass();

15
Newbies इस तरह की चीजों को "हैकिश" मानते हैं, अधिक अनुभवी देवता इसे "मुहावरेदार" कहते हैं।
डॉक्टर ब्राउन

यदि वस्तु एक मूल्य वस्तु की तरह लगती है ("मुहावरेदार बोल में" मूल्य शब्दार्थ है), अपने प्रकार के मूल्य का MyClassएक public static readonlyसदस्य प्रदान करना चाहिए EmptyString.EmptyMSDN पर देखें ।
rwong


5
क्या कोई ??=ऑपरेटर नहीं है?
aviv

1
@aviv काश वहाँ था!
लोरेन Pechtel

जवाबों:


16

मैं हर समय अशक्त coalescing ऑपरेटर का उपयोग करें। मुझे इसकी सहमति पसंद है।

मैं इस ऑपरेटर को प्रकृति में टर्नेरी ऑपरेटर (ए? बी: सी) के समान मानता हूं। यह पढ़ने से पहले थोड़ा अभ्यास करता है, यह दूसरी प्रकृति है, लेकिन एक बार जब आप इसका उपयोग कर लेते हैं तो मुझे लगता है कि पठनीयता में सुधार होता है।

इसके अलावा, आपके द्वारा वर्णित स्थिति केवल एक परिदृश्य है जहां ऑपरेटर उपयोगी है। इस तरह से निर्माणों को बदलना भी आसान है:

if (value != null)
{
    return value;
}
else
{ 
    return otherValue;
}

या

return value != null ? value : otherValue;

साथ में

return value ?? otherValue;

निश्चित रूप से इस ऑपरेटर के उपयोग के बारे में सामान्य रूप से सहमत हैं। जब मैं इसका उपयोग करने के संदर्भ देखता हूं, हालांकि, यह आमतौर पर कुछ ऐसा होता है myObject = myObject2 ?? myObject3। मैं जिस चीज के बारे में सोच रहा था, वह विशेष रूप से ऑपरेटर का उपयोग कर रहा है जब तक कि यह अशक्त न हो।
grin0048

2
मुझे लगता है कि दोनों ही मामलों में एक ही तर्क लागू होता है। यह एक ही तर्क व्यक्त करने का अधिक संक्षिप्त तरीका है।
17 की 26

मुझे याद है कि एक बार उन तीन रूपों में से प्रत्येक के लिए आईएल देखना। पहले और दूसरे समान थे, लेकिन तीसरे को एक फैशन में अनुकूलित किया गया था क्योंकि यह मान सकता nullथा कि यह तुलना थी।
जेसी सी। स्लाइसर

2

मैं जिस चीज के बारे में सोच रहा था, वह विशेष रूप से ऑपरेटर का उपयोग कर रहा है जब तक कि यह अशक्त न हो।

?? operatorअशक्त-वालों ऑपरेटर कहा जाता है और व्यर्थ मूल्य प्रकार या संदर्भ प्रकार के लिए एक डिफ़ॉल्ट मान परिभाषित करने के लिए प्रयोग किया जाता है। यदि ऑपरेंड शून्य नहीं है, तो यह बाएं हाथ का ऑपरेंड देता है; अन्यथा यह सही ऑपरेंड देता है।

myObject = myObject ?? new myObject(); - instantiate default value of object

Null-coalescing ऑपरेटर के बारे में अधिक विवरण और कोड नमूना - MSDN आलेख

यदि आप more than nullableस्थिति की जांच करते हैं, तो एक विकल्प के रूप में आप टर्नरी ऑपरेटर का उपयोग कर सकते हैं।

टर्नरी ऑपरेटर

तुम भी पर लग सकता है : ऑपरेटर । इसे टर्नेरी या सशर्त ऑपरेटर कहा जाता है । सशर्त ऑपरेटर (:) एक बूलियन अभिव्यक्ति के मूल्य के आधार पर दो में से एक मान लौटाता है।

एक अशक्त प्रकार में एक मान हो सकता है, या यह अपरिभाषित हो सकता है। ?? जब कोई अशक्त प्रकार एक अशक्त प्रकार को सौंपा जाता है, तो ऑपरेटर डिफ़ॉल्ट मान लौटाता है। यदि आप एक अशक्त मान प्रकार को बिना उपयोग किए बिना अशक्त मान प्रकार निर्दिष्ट करने का प्रयास करते हैं ?? ऑपरेटर, आप एक संकलन-समय त्रुटि उत्पन्न करेंगे। यदि आप किसी कास्ट का उपयोग करते हैं, और अशक्त मान वर्तमान में अपरिभाषित है, तो InvalidOperationException अपवाद को फेंक दिया जाएगा।

MSDN से एक कोड उदाहरण -: ऑपरेटर (C # संदर्भ) :

int? input = Convert.ToInt32(Console.ReadLine());
string classify;

// ?: conditional operator.
classify = (input.HasValue) ? ((input < 0) ? "negative" : "positive") : "undefined";

इसलिए प्रश्न से उदाहरण लेना और सशर्त ऑपरेटर को लागू करना, हमारे पास कुछ ऐसा होगा myObject = (myObject == null) ? new myClass() : myObject। इसलिए, जब तक कि मैं सशर्त ऑपरेटर के बेहतर उपयोग को याद नहीं कर रहा हूं, तब तक यह स्वयं को एक वस्तु सेट करने के साथ एक ही "समस्या" है (यदि यह शून्य नहीं है) अशक्त-संचालक ऑपरेटर के रूप में - और यह कम संक्षिप्त है।
grin0048

यदि आप एक से अधिक स्थिति (शून्य से अधिक शून्य और अधिक नहीं) के लिए जाँच कर रहे हैं - तो सशर्त ऑपरेटर करेगा। हालाँकि, बस शून्य जाँच के लिए काम करेगा ?? ऑपरेटर।
यूसुबोव

2

मुझे नहीं लगता कि यह परिदृश्य विशिष्ट है (या कम से कम होना चाहिए)।

यदि आप चाहते हैं कि कुछ फ़ील्ड का डिफ़ॉल्ट मान न हो null, तो उसे फ़ील्ड इनिशलाइज़र में सेट करें:

myClass myObject = new myClass();

या, यदि आरंभीकरण अधिक जटिल है, तो इसे कंस्ट्रक्टर में सेट करें।

यदि आप myClassकेवल तभी बनाना चाहते हैं जब आपको वास्तव में इसकी आवश्यकता हो (जैसे कि इसे बनाने में लंबा समय लगता है), तो आप इसका उपयोग कर सकते हैं Lazy<T>:

Lazy<myClass> myObject = new Lazy<myClass>();

(यह डिफ़ॉल्ट कंस्ट्रक्टर को कॉल करता है। यदि इनिशियलाइज़ेशन अधिक जटिल है, तो लैम्बडा पास myClassकरें जो Lazy<T>कंस्ट्रक्टर को बनाता है ।)

मान का उपयोग करने के लिए, उपयोग करें myObject.Value, जो आरंभीकरण को कॉल करेगा यदि यह पहली बार है जब आप एक्सेस कर रहे हैं myObject.Value


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

@ratchetfreak हाँ, इसीलिए मैंने पहले फील्ड इनिशियलाइज़र का सुझाव दिया था।
23

अन्य मामले भी हैं। मैं इस समय क्या देख रहा हूं: पहला पास अपवाद मामलों को सेट करता है। दूसरा पास सब कुछ के लिए चूक निर्धारित करता है। ?? = लाइन को आधे में काटेगा।
लोरेन Pechtel

1

मुझे विशेष ??रूप से वैकल्पिक विधि मापदंडों के साथ संयोजन का उपयोग करना पसंद है । मैं ओवरलोड की आवश्यकता को सीमित करता हूं और यह सुनिश्चित करता हूं कि चीज का मूल्य हो।

public void DoSomething (MyClass thing1 = null) {
    thing1 = thing1 ?? new MyClass();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.