असाइनमेंट स्टेटमेंट एक मान क्यों लौटाते हैं?


126

इसकी अनुमति है:

int a, b, c;
a = b = c = 16;

string s = null;
while ((s = "Hello") != null) ;

मेरी समझ में, असाइनमेंट s = ”Hello”;को केवल “Hello”असाइन करने का कारण होना चाहिए s, लेकिन ऑपरेशन किसी भी मूल्य पर वापस नहीं आना चाहिए। अगर यह सच था, तो ((s = "Hello") != null)एक त्रुटि पैदा करेगा, क्योंकि nullकुछ भी नहीं की तुलना में होगा।

मान वापस करने के लिए असाइनमेंट स्टेटमेंट की अनुमति देने के पीछे क्या तर्क है?


44
संदर्भ के लिए, इस व्यवहार को सी # कल्पना में परिभाषित किया गया है : "एक साधारण असाइनमेंट अभिव्यक्ति का परिणाम बाएं ऑपरेंड को सौंपा गया मूल्य है। परिणाम में बाएं ऑपरेंड के समान प्रकार होता है और इसे हमेशा मूल्य के रूप में वर्गीकृत किया जाता है।"
माइकल पेट्रोत्ता

1
@Skurmedel मैं नीच नहीं हूं, मैं आपसे सहमत हूं। लेकिन शायद इसलिए कि इसे एक लफ्फाजी वाला सवाल समझा गया था?
जेमिथ

पास्कल / डेल्फी असाइनमेंट में: = कुछ नहीं देता है। मुझे इससे घृणा है।
एंड्री

20
सी शाखा में भाषाओं के लिए मानक। असाइनमेंट एक्सप्रेशन हैं।
हंस पासेंट

"असाइनमेंट ... केवल" हैलो "को एस को सौंपा जाना चाहिए, लेकिन ऑपरेशन किसी भी मूल्य पर वापस नहीं आना चाहिए" - क्यों? "मान को वापस करने के लिए असाइनमेंट स्टेटमेंट की अनुमति देने के पीछे क्या तर्क है?" - क्योंकि यह उपयोगी है, जैसा कि आपके स्वयं के उदाहरण प्रदर्शित करते हैं। (खैर, आपका दूसरा उदाहरण मूर्खतापूर्ण है, लेकिन while ((s = GetWord()) != null) Process(s);ऐसा नहीं है)।
जिम बाल्टर

जवाबों:


160

मेरी समझ में, असाइनमेंट s = "हैलो"; केवल "हैलो" को एस को सौंपा जाना चाहिए, लेकिन ऑपरेशन किसी भी मूल्य पर वापस नहीं आना चाहिए।

आपकी समझ 100% गलत है। क्या आप समझा सकते हैं कि आप इस झूठी बात को क्यों मानते हैं?

मान वापस करने के लिए असाइनमेंट स्टेटमेंट की अनुमति देने के पीछे क्या तर्क है?

सबसे पहले, असाइनमेंट स्टेटमेंट एक मूल्य का उत्पादन नहीं करते हैं। असाइनमेंट का भाव एक मान उत्पन्न करते हैं। एक असाइनमेंट अभिव्यक्ति एक कानूनी बयान है; केवल कुछ मुट्ठी भर अभिव्यक्तियाँ हैं जो C # में कानूनी कथन हैं: एक अभिव्यक्ति, उदाहरण निर्माण, वेतन वृद्धि, गिरावट, मंगलाचरण और असाइनमेंट अभिव्यक्तियों का उपयोग किया जा सकता है जहाँ एक कथन की अपेक्षा की जाती है।

C # में केवल एक प्रकार की अभिव्यक्ति है, जो किसी प्रकार के मूल्य का उत्पादन नहीं करती है, अर्थात्, किसी चीज़ का एक आह्वान जो शून्य को लौटाने के रूप में टाइप किया जाता है। (या, समतुल्य, बिना किसी संबंधित परिणाम मान के किसी कार्य का इंतजार।) हर दूसरे प्रकार की अभिव्यक्ति एक मूल्य या चर या संदर्भ या संपत्ति का उपयोग या घटना का उपयोग, और इसी तरह का उत्पादन करती है।

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

इस सुविधा की अनुमति देने के पीछे तर्क यह है क्योंकि (1) यह अक्सर सुविधाजनक होता है और (2) यह सी जैसी भाषाओं में मुहावरेदार होता है।

एक व्यक्ति ध्यान दे सकता है कि यह प्रश्न भीख में दिया गया है: सी-जैसी भाषाओं में यह मुहावरा क्यों है?

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


1
पता नहीं था कि जो कुछ भी मूल्य देता है (उदाहरण के निर्माण को एक अभिव्यक्ति माना जाता है)
user437291

9
@ user437291: यदि उदाहरण निर्माण एक अभिव्यक्ति नहीं था, तो आप निर्मित वस्तु के साथ कुछ नहीं कर सकते थे - आप इसे कुछ नहीं दे सकते थे, आप इसे एक विधि में पारित नहीं कर सकते थे, और आप किसी भी तरीके को नहीं कह सकते थे। इस पर। बहुत बेकार होगा, है ना?
तिमवी

1
एक चर को बदलना वास्तव में "बस" असाइनमेंट ऑपरेटर का एक साइड इफेक्ट है, जो एक अभिव्यक्ति का निर्माण करता है, अपने प्राथमिक उद्देश्य के रूप में एक मूल्य प्राप्त करता है।
mk12

2
"आपकी समझ 100% गलत है।" - जबकि अंग्रेजी के ओपी का उपयोग सबसे बड़ा नहीं है, उसकी "समझ" इस बारे में है कि मामला क्या होना चाहिए , यह एक राय बनाता है, इसलिए यह "100% गलत" होने की तरह नहीं है। । कुछ भाषा डिजाइनर ओपी के "चाहिए" से सहमत हैं, और असाइनमेंट का कोई मूल्य नहीं है या अन्यथा उन्हें सबएक्सप्रेस से होने पर प्रतिबंध है। मुझे लगता है कि यह =/ ==टाइपो के लिए एक अतिशयोक्ति है , जिसे आसानी से संबोधित किया जाता है, =जब तक कि इसे छोटा न किया जाए। उदाहरण के लिए, if ((x = y))या if ((x = y) == true)अनुमति है लेकिन if (x = y)नहीं है।
जिम बाल्टर

"इस बात से अवगत नहीं थे कि जो कुछ भी एक मूल्य देता है ... को एक अभिव्यक्ति माना जाता है" - हम्म ... हर चीज जो एक मूल्य लौटाती है उसे एक अभिव्यक्ति माना जाता है - दो लगभग समानार्थी हैं।
जिम बाल्टर

44

क्या आपने जवाब नहीं दिया है? यह आपके द्वारा उल्लिखित निर्माणों के प्रकार को सक्षम करने के लिए है।

एक सामान्य मामला जहां असाइनमेंट ऑपरेटर की इस संपत्ति का उपयोग किया जाता है, एक फ़ाइल से लाइनें पढ़ रहा है ...

string line;
while ((line = streamReader.ReadLine()) != null)
    // ...

1
+1 इसे इस निर्माण के सबसे व्यावहारिक उपयोगों में से एक होना है
माइक बर्टन

11
मैं वास्तव में इसे वास्तव में सरल संपत्ति शुरुआती के लिए पसंद करता हूं, लेकिन आपको सावधान रहना होगा और पठनीयता के लिए "सरल" कम के लिए अपनी रेखा खींचनी होगी: return _myBackingField ?? (_myBackingField = CalculateBackingField());अशक्त और असाइन करने के लिए जाँच करने की तुलना में बहुत कम chaff।
टॉम मेफ़ील्ड

34

असाइनमेंट एक्सप्रेशन का मेरा पसंदीदा उपयोग आलसी प्रारंभिक गुण के लिए है।

private string _name;
public string Name
{
    get { return _name ?? (_name = ExpensiveNameGeneratorMethod()); }
}

5
यही कारण है कि इतने सारे लोगों ने ??=वाक्य रचना का सुझाव दिया है ।
विन्यासकर्ता

27

एक के लिए, यह आपको अपने असाइनमेंट को चेन करने की अनुमति देता है, जैसा कि आपके उदाहरण में:

a = b = c = 16;

दूसरे के लिए, यह आपको एकल अभिव्यक्ति में परिणाम प्रदान करने और जांचने की अनुमति देता है:

while ((s = foo.getSomeString()) != null) { /* ... */ }

दोनों संभवतः संदिग्ध कारण हैं, लेकिन निश्चित रूप से ऐसे लोग हैं जो इन निर्माणों को पसंद करते हैं।


5
+1 चेनिंग एक महत्वपूर्ण विशेषता नहीं है, लेकिन जब बहुत सारी चीजें नहीं होती हैं, तो यह "बस काम करता है" देखकर अच्छा लगता है।
माइक बर्टन

चाइनिंग के लिए भी +1; मैं हमेशा एक विशेष मामले के रूप में सोचता हूं जो "अभिव्यक्ति वापसी मूल्यों" के प्राकृतिक दुष्प्रभाव के बजाय भाषा द्वारा नियंत्रित किया गया था।
कालेब बेल

2
यह आपको रिटर्न में असाइनमेंट का उपयोग करने की भी अनुमति देता है:return (HttpContext.Current.Items["x"] = myvar);
सर्ज Shultz

14

पहले से बताए गए कारणों के अलावा (लूप्स वगैरह के भीतर असाइनमेंट चेनिंग, सेट-एंड-टेस्ट), उस कथन का ठीक से उपयोग करने के लिए जिसे usingआपको इस सुविधा की आवश्यकता है:

using (Font font3 = new Font("Arial", 10.0f))
{
    // Use font3.
}

MSDN उपयोग कथन के बाहर डिस्पोजेबल ऑब्जेक्ट को घोषित करने को हतोत्साहित करता है, क्योंकि यह निपटाने के बाद भी स्कोप में रहेगा (MSDN लेख मैं जुड़ा हुआ देखें)।


4
मुझे नहीं लगता कि यह वास्तव में प्रति सेशन का काम है।
केनी

1
@kenny: उह ... नहीं, लेकिन मैंने कभी भी यह दावा नहीं किया था कि या तो। जैसा कि मैंने कहा, पहले से बताए गए कारणों से अलग - जिसमें असाइनमेंट चेनिंग शामिल है - उपयोग करने वाले कथन का उपयोग करना अधिक कठिन होगा यह इस तथ्य के लिए नहीं था कि असाइनमेंट ऑपरेटर असाइनमेंट ऑपरेशन का परिणाम देता है। यह वास्तव में असाइनमेंट चेनिंग से संबंधित नहीं है।
मार्टिन टॉर्नवॉल

1
लेकिन जैसा कि एरिक ने ऊपर उल्लेख किया है, "असाइनमेंट स्टेटमेंट एक मान नहीं लौटाते हैं"। यह वास्तव में उपयोग करने वाले कथन का सिर्फ भाषा वाक्य है, इसका प्रमाण यह है कि कोई एक उपयोग कथन में "असाइनमेंट एक्सप्रेशन" का उपयोग नहीं कर सकता है।
केनी

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

2
@kenny: वास्तव में, कोई भी परिभाषा और असाइनमेंट स्टेटमेंट या किसी भी अभिव्यक्ति का उपयोग कर सकता है using। इन सभी कानूनी हैं: using (X x = new X()), using (x = new X()), using (x)। हालांकि, इस उदाहरण में, उपयोग कथन की सामग्री एक विशेष वाक्यविन्यास है जो मान लौटाने वाले असाइनमेंट पर बिल्कुल भरोसा नहीं करता है - Font font3 = new Font("Arial", 10.0f)एक अभिव्यक्ति नहीं है और किसी भी स्थान पर मान्य नहीं है जो अभिव्यक्तियों की अपेक्षा करता है।
विन्यासकर्ता

10

मैं अपने जवाब में किए गए एक विशेष बिंदु एरिक लिपर्ट के बारे में विस्तार से बताना चाहता हूं और किसी विशेष अवसर पर स्पॉटलाइट डालता हूं जिसे किसी और ने नहीं छुआ है। एरिक ने कहा:

[...] एक असाइनमेंट लगभग हमेशा उस मान को पीछे छोड़ देता है जिसे अभी एक रजिस्टर में सौंपा गया था।

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

इस सूत्र के उत्तर में निर्मित सभी उदाहरणों के लिए 'कुशल' हाँ। लेकिन प्रापर्टी और इंडेक्सर्स के मामले में कुशल, जो एक्सेस प्राप्त करते हैं और एक्सेसर्स सेट करते हैं? हर्गिज नहीं। इस कोड पर विचार करें:

class Test
{
    public bool MyProperty { get { return true; } set { ; } }
}

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

Test test = new Test();

if ((test.MyProperty = false) == true)
    Console.WriteLine("Please print this text.");

else
    Console.WriteLine("Unexpected!!");

लगता है क्या यह प्रिंट? यह प्रिंट करता है Unexpected!!। जैसा कि यह पता चला है, सेट एक्सेसर वास्तव में कहा जाता है, जो कुछ भी नहीं करता है। लेकिन इसके बाद, गेट एक्सेसर को कभी नहीं बुलाया जाता है। असाइनमेंट केवल उस falseमूल्य को पीछे छोड़ देता है जिसे हमने अपनी संपत्ति को असाइन करने की कोशिश की थी। और यह falseमान है कि यदि कथन का मूल्यांकन होता है।

मैं एक वास्तविक दुनिया उदाहरण के साथ समाप्त करूँगा जिसने मुझे इस मुद्दे पर शोध किया। मैंने एक इंडेक्सर बनाया जो एक संग्रह के लिए एक सुविधाजनक आवरण था ( List<string>) जो कि मेरा एक वर्ग एक निजी चर के रूप में था।

इंडेक्सर को भेजा गया पैरामीटर एक स्ट्रिंग था, जिसे मेरे संग्रह में एक मूल्य के रूप में माना जाना था। यदि यह मान सूची में मौजूद है या नहीं, तो एक्सेस एक्सेसर केवल सही या गलत लौटाएगा। इस प्रकार प्राप्तकर्ता उपयोग करने का एक और तरीका थाList<T>.Contains विधि ।

यदि अनुक्रमणिका के सेट एक्सेसर को एक तर्क के रूप में स्ट्रिंग के साथ बुलाया गया था और सही ऑपरेंड एक बूल था true, तो वह उस पैरामीटर को सूची में जोड़ देगा। लेकिन अगर वही पैरामीटर एक्सेसर को भेजा गया था और सही ऑपरेंड एक बूल था false, तो वह सूची से तत्व को हटा देगा। इस प्रकार सेट एक्सेसर दोनों के लिए एक सुविधाजनक विकल्प के रूप में इस्तेमाल किया गया था List<T>.AddऔरList<T>.Remove

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

if (myObject["stringValue"] = true)
    ; // Set operation succeeded..!

लेकिन जैसा कि मेरे पहले के उदाहरण से पता चलता है, एक्सेस एक्सेसर जो यह देखने वाला है कि क्या वास्तव में मूल्य सूची में है भी नहीं। trueमूल्य हमेशा पीछे प्रभावी रूप से नष्ट जो कुछ भी तर्क मैं अपने get एक्सेसर में लागू किया था छोड़ दिया गया था।


बहुत दिलचस्प जवाब। और इसने मुझे परीक्षण-संचालित विकास के बारे में सकारात्मक रूप से सोचने पर मजबूर कर दिया है।
इलियट

1
हालांकि यह दिलचस्प है, यह एरिक के जवाब पर टिप्पणी है, ओपी के सवाल का जवाब नहीं है।
जिम बाल्टर

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

6

यदि असाइनमेंट ने मान वापस नहीं किया है, तो लाइन a = b = c = 16 या तो काम नहीं करेगी।

साथ ही चीजों को लिखने में सक्षम होने के नाते while ((s = readLine()) != null) होना कभी-कभी उपयोगी हो सकता है।

तो असाइनमेंट को असाइन किए गए मान को वापस करने का कारण, आपको उन चीजों को करने देना है।


किसी का उल्लेख नहीं है नुकसान - मैं सोच रहा था कि असाइनमेंट अशक्त क्यों नहीं लौट सकता है, ताकि सामान्य असाइनमेंट बनाम तुलना बग 'अगर (कुछ = 1) {}' हमेशा वापस लौटने के बजाय संकलन करने में विफल हो। अब मैं देख रहा हूँ कि अन्य मुद्दों को पैदा करेगा!
जॉन

1
@ उस बग को आसानी से रोका जा सकता है या =एक अभिव्यक्ति में होने के बारे में चेतावनी देकर रोका जा सकता है जो कि कोष्ठक नहीं है (यदि / जबकि बयान स्वयं के परगनों की गिनती नहीं है)। gcc ऐसी चेतावनियाँ देता है और इस तरह अनिवार्य रूप से C / C ++ प्रोग्राम से बग के इस वर्ग को समाप्त कर दिया है जो इसके साथ संकलित हैं। यह शर्म की बात है कि अन्य संकलक लेखकों ने इस पर बहुत कम ध्यान दिया है और जीसीसी में कई अन्य अच्छे विचार हैं।
जिम बाल्टर

4

मुझे लगता है कि आप गलत समझ रहे हैं कि कैसे पार्सर उस वाक्य रचना की व्याख्या करने जा रहा है। असाइनमेंट का मूल्यांकन पहले किया जाएगा , और फिर परिणाम की तुलना NULL से की जाएगी, अर्थात कथन इसके बराबर है:

s = "Hello"; //s now contains the value "Hello"
(s != null) //returns true.

जैसा कि दूसरों ने बताया है, असाइनमेंट का परिणाम असाइन किया गया मान है। मुझे होने वाले लाभ की कल्पना करना कठिन लगता है

((s = "Hello") != null)

तथा

s = "Hello";
s != null;

नहीं के बराबर ...


जब आप एक व्यावहारिक अर्थ से सही हैं कि आपकी दो पंक्तियाँ आपके कथन के बराबर हैं कि असाइनमेंट वापस नहीं आ रहा है तो तकनीकी रूप से सही नहीं है। मेरी समझ यह है कि एक असाइनमेंट का परिणाम एक मान है (C # कल्पना के अनुसार), और इस अर्थ में 1 + 2 + 3 की तरह एक अभिव्यक्ति में अतिरिक्त ऑपरेटर कहने से अलग नहीं है
स्टीव एलिंगर

3

मुझे लगता है कि मुख्य कारण सी ++ और सी के साथ (जानबूझकर) समानता है, जिससे एसिगमेंट ऑपरेटर (और बहुत सी अन्य भाषा निर्माण) करना उनके सी ++ समकक्षों की तरह व्यवहार करते हैं, बस कम से कम आश्चर्य के सिद्धांत का पालन करते हैं, और किसी भी प्रोग्रामर को एक और घुंघराले रंग के साथ आते हैं। ब्रैकेट भाषा ज्यादा विचार खर्च किए बिना उनका उपयोग कर सकती है। C ++ प्रोग्रामर के लिए चुनना आसान होना C # के लिए मुख्य डिज़ाइन लक्ष्यों में से एक था।


2

दो कारणों से आप अपने पद
1 में शामिल होते हैं) तो आप a = b = c = 16
2 कर सकते हैं ) ताकि आप परीक्षण कर सकें कि क्या कोई असाइनमेंट सफल हुआ है if ((s = openSomeHandle()) != null)


1

तथ्य यह है कि 'ए ++' या 'प्रिंटफ ("फू")' स्व-निहित कथन के रूप में या बड़े अभिव्यक्ति के एक भाग के रूप में उपयोगी हो सकता है, इसका मतलब यह है कि सी को इस संभावना के लिए अनुमति देना है कि अभिव्यक्ति परिणाम हो सकता है या नहीं हो सकता है। उपयोग किया गया। यह देखते हुए, वहाँ एक सामान्य धारणा है कि भाव जो उपयोगी रूप से एक मूल्य 'वापसी' कर सकते हैं और साथ ही ऐसा कर सकते हैं। असाइनमेंट चाइनिंग सी में थोड़ा "दिलचस्प" हो सकता है, और सी ++ में और भी दिलचस्प हो सकता है, अगर प्रश्न के सभी चर ठीक तरह से नहीं होते हैं। इस तरह के usages शायद सबसे अच्छा बचा जाता है।


1

एक और बेहतरीन उदाहरण उपयोग-मामला, मैं हर समय इसका उपयोग करता हूं:

var x = _myVariable ?? (_myVariable = GetVariable());
//for example: when used inside a loop, "GetVariable" will be called only once

0

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

अब x = y = b = c = 2 + 3सी-स्टाइल भाषा की तुलना में अंकगणित में कुछ अलग है; अंकगणित में इसका जोर होता है, हम कहते हैं कि x, y आदि के बराबर है और C- शैली की भाषा में यह एक निर्देश है जो इसे निष्पादित होने के बाद x के बराबर y आदि बनाता है।

इसने कहा, अंकगणित और कोड के बीच अभी भी पर्याप्त संबंध है कि जब तक एक अच्छा कारण नहीं है, तो अंकगणित में जो स्वाभाविक है उसे अस्वीकार करने का कोई मतलब नहीं है। (दूसरी बात यह है कि सी-स्टाइल भाषाओं ने बराबरी के प्रतीक के उपयोग से लिया था = समानता तुलना के लिए == का उपयोग। यहां हालांकि, क्योंकि सही-सबसे == एक मान लौटाता है, इस तरह की चेनिंग असंभव होगी।)


@JimBalter मुझे आश्चर्य है कि क्या, पाँच साल में, आप वास्तव में इसके खिलाफ तर्क दे सकते हैं।
जॉन हैना

@JimBalter नहीं, आपकी दूसरी टिप्पणी वास्तव में एक काउंटर तर्क है, और एक ध्वनि है। मेरी सोच का प्रतिशोध था क्योंकि आपकी पहली टिप्पणी नहीं थी। फिर भी, जब गणित सीखने हम सीखते हैं a = b = cमतलब है कि aऔर bऔर cएक ही बात कर रहे हैं। सी शैली की भाषा सीखते समय हम सीखते हैं कि बाद में a = b = c, aऔर bजैसी ही बात है c। शब्दार्थ में निश्चित रूप से अंतर है, जैसा कि मेरा उत्तर खुद कहता है, लेकिन फिर भी जब एक बच्चे के रूप में मैंने पहली बार एक ऐसी भाषा में प्रोग्राम करना सीखा, जो =असाइनमेंट के लिए उपयोग किया था, लेकिन a = b = cयह मुझे अनुचित नहीं लगा, हालांकि ...
जॉन हैना

... अपरिहार्य क्योंकि वह भाषा भी =समानता की तुलना के लिए उपयोग की जाती है, इसलिए सी-स्टाइल भाषाओं में इसका a = b = cमतलब क्या होगा a = b == c। मैंने पाया कि सी में जंजीर की अनुमति बहुत अधिक सहज है क्योंकि मैं अंकगणित के लिए एक सादृश्य आकर्षित कर सकता हूं।
जॉन हैना

0

मुझे असाइनमेंट रिटर्न वैल्यू का उपयोग करना पसंद है जब मुझे सामान का एक गुच्छा अपडेट करने की आवश्यकता होती है और कोई परिवर्तन नहीं था या नहीं

bool hasChanged = false;

hasChanged |= thing.Property != (thing.Property = "Value");
hasChanged |= thing.AnotherProperty != (thing.AnotherProperty = 42);
hasChanged |= thing.OneMore != (thing.OneMore = "They get it");

return hasChanged;

हालांकि सावधान रहें। आपको लगता है कि आप इसे छोटा कर सकते हैं:

return thing.Property != (thing.Property = "Value") ||
    thing.AnotherProperty != (thing.AnotherProperty = 42) ||
    thing.OneMore != (thing.OneMore = "They get it");

लेकिन यह वास्तव में या पहले सच का पता चलने के बाद बयानों का मूल्यांकन करना बंद कर देगा। इस मामले में इसका मतलब यह है कि एक बार यह मान अलग होने के बाद पहला मान असाइन करना बंद कर देता है।

इसके साथ खेलने के लिए https://dotnetfiddle.net/e05Rh8 देखें

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