कौन सा बेहतर है, रिटर्न वैल्यू या आउट पैरामीटर?


147

यदि हम एक विधि से एक मूल्य प्राप्त करना चाहते हैं, तो हम इस तरह से वापसी मूल्य का उपयोग कर सकते हैं:

public int GetValue(); 

या:

public void GetValue(out int x);

मैं वास्तव में उनके बीच के अंतरों को नहीं समझता हूं, और इसलिए, यह नहीं जानते कि कौन सा बेहतर है। क्या आप मुझे यह समझा सकते हैं?

धन्यवाद।


3
मैं चाहता हूं कि उदाहरण के लिए, C # में कई वापसी मूल्य हैं, जैसे कि पायथन।
ट्रैप

12
@ रैप आप चाहें तो वापस कर सकते Tupleहैं, लेकिन आम सहमति यह है कि यदि आपको एक से अधिक चीजों को वापस करने की आवश्यकता है, तो चीजें आमतौर पर किसी न किसी तरह से संबंधित होती हैं और यह संबंध आमतौर पर एक वर्ग के रूप में व्यक्त किया जाता है।
फराप

2
@ वर्तमान आकार में C # में Tuples केवल बदसूरत हैं, लेकिन यह सिर्फ मेरी राय है। दूसरी ओर, "सामान्य आम सहमति" का मतलब उपयोगिता और उत्पादकता के दृष्टिकोण से कुछ भी नहीं है। आप उसी श्रेणी के लिए मानों के एक जोड़े को वापस करने के लिए एक वर्ग नहीं बनायेंगे उसी कारण से जब आप रेफरी / आउट पैरामीटर के रूप में मूल्यों के एक जोड़े को वापस करने के लिए एक वर्ग नहीं बनाएंगे।
जाल

@ return Tuple.Create(x, y, z);यह बदसूरत नहीं है। इसके अलावा, उन्हें भाषा के स्तर पर पेश करने में देर हो चुकी है। कारण यह है कि मैं रेफरी / आउट पैरामीटर से मानों को लौटाने के लिए एक वर्ग नहीं बनाऊंगा क्योंकि रेफरी / आउट पारम केवल बड़े म्यूटेबल स्ट्रक्चर्स (जैसे मैट्रिसेस) या वैकल्पिक मानों के लिए वास्तव में समझ में आता है, और बाद में डिबेटेबल है।
फरेप

@Pharap C # टीम सक्रिय रूप से भाषा के स्तर पर ट्यूपल्स को पेश करना चाहती है। हालांकि यह .NET नेटिंग में अब विकल्पों के पूरे बहुतायत का स्वागत करता है - अनाम प्रकार, .NET Tuple<>और C # tuples !. मैं सिर्फ सी # की अनुमति देता है संकलक autoइनफ्लाडिंग प्रकार (जैसे डलांग में) के तरीकों से अनाम प्रकारों की वापसी ।
नवाफल

जवाबों:


153

वापसी मान लगभग हमेशा सही विकल्प होता है जब विधि के पास वापस लौटने के लिए कुछ और नहीं होता है। (वास्तव में, मैं ऐसे किसी भी मामले के बारे में नहीं सोच सकता, जहां मैं कभी भीout पैरामीटर के साथ एक शून्य विधि चाहता हूं, अगर मेरे पास विकल्प था। Deconstructभाषा-समर्थित डिकंस्ट्रक्शन के लिए C # 7 के तरीके इस नियम के बहुत, बहुत दुर्लभ अपवाद के रूप में कार्य करते हैं। ।)

कुछ और के अलावा, यह अलग से चर घोषित करने के लिए फोन करने वाले को रोकता है:

int foo;
GetValue(out foo);

बनाम

int foo = GetValue();

आउट मान भी इस तरह से विधि को रोकने से रोकते हैं:

Console.WriteLine(GetValue().ToString("g"));

(वास्तव में, यह संपत्ति के साथ समस्याओं में से एक के रूप में अच्छी तरह से बसता है, और यही कारण है कि बिल्डर पैटर्न उन तरीकों का उपयोग करता है जो बिल्डर को वापस करते हैं, उदाहरण के लिए myStringBuilder.Append(xxx).Append(yyy)।)

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

वापसी मान FTW।

संपादित करें: क्या चल रहा है के संदर्भ में ...

मूल रूप से जब आप "आउट" पैरामीटर के तर्क में पास होते हैं, तो आपको एक चर में पास करना होगा। (ऐरे तत्वों को चर के रूप में भी वर्गीकृत किया जाता है।) आपके द्वारा कॉल की जाने वाली विधि में पैरामीटर के लिए इसके स्टैक पर "नया" वैरिएबल नहीं है - यह भंडारण के लिए आपके चर का उपयोग करता है। चर में कोई भी परिवर्तन तुरंत दिखाई देते हैं। यहाँ एक उदाहरण है जो अंतर दिखा रहा है:

using System;

class Test
{
    static int value;

    static void ShowValue(string description)
    {
        Console.WriteLine(description + value);
    }

    static void Main()
    {
        Console.WriteLine("Return value test...");
        value = 5;
        value = ReturnValue();
        ShowValue("Value after ReturnValue(): ");

        value = 5;
        Console.WriteLine("Out parameter test...");
        OutParameter(out value);
        ShowValue("Value after OutParameter(): ");
    }

    static int ReturnValue()
    {
        ShowValue("ReturnValue (pre): ");
        int tmp = 10;
        ShowValue("ReturnValue (post): ");
        return tmp;
    }

    static void OutParameter(out int tmp)
    {
        ShowValue("OutParameter (pre): ");
        tmp = 10;
        ShowValue("OutParameter (post): ");
    }
}

परिणाम:

Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10

अंतर "पोस्ट" चरण पर है - अर्थात स्थानीय चर या पैरामीटर को बदलने के बाद। ReturnValue परीक्षण में, यह स्थिर valueचर के लिए कोई फर्क नहीं पड़ता है । आउटपैरमीटर परीक्षण में, valueचर को रेखा से बदल दिया जाता हैtmp = 10;


2
आपने मुझे विश्वास दिलाया कि वापसी का मूल्य बहुत बेहतर है :)। लेकिन मुझे अभी भी आश्चर्य है कि "गहराई में" क्या होता है। मेरा मतलब है, वापसी मान, और आउट पैरामीटर, क्या वे जिस तरह से बनाए गए हैं, असाइन किए गए और वापस लौटे हैं, क्या वे अलग हैं?
क्वान माई

1
ट्रायपर्स सबसे अच्छा उदाहरण है जब एक आउट परम का उपयोग उचित और साफ है। हालाँकि मैंने इसे विशेष मामलों में उपयोग किया है जैसे कि (WorkSucceeded (बाहर सूची <string> त्रुटियाँ) जो मूल रूप से TryParse के समान पैटर्न है
चाड ग्रांट

2
एक गरीब एक अनजाना जवाब। जैसा कि इस सवाल पर टिप्पणियों में बताया गया है , बाहर के मापदंडों के कई उपयोगी फायदे हैं। आउट बनाम रिटर्न के बीच की स्थिति पर निर्भर होना चाहिए।
अनारोनोसवेल

2
@ARonsnoswell: कौन सी सटीक टिप्पणियां? ध्यान रखें कि का उदाहरण Dictionary.TryGetValueहै नहीं लागू यहाँ, कि एक शून्य विधि नहीं है के रूप में। क्या आप बता सकते हैं कि आप रिटर्न वैल्यू के बजाय एक outपैरामीटर क्यों चाहते हैं ? (यहां तक ​​कि , मैं एक वापसी मूल्य पसंद करूंगा जिसमें सभी आउटपुट जानकारी शामिल हैं, व्यक्तिगत रूप से। NodaTime का एक उदाहरण देखें कि इसे कैसे डिज़ाइन किया गया होगा।)TryGetValueParseResult<T>
जॉन स्कीट

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

26

क्या बेहतर है, आपकी विशेष स्थिति पर निर्भर करता है। एक कारण से outमौजूद है एक विधि कॉल से एक से अधिक मान लौटने की सुविधा के लिए है:

public int ReturnMultiple(int input, out int output1, out int output2)
{
    output1 = input + 1;
    output2 = input + 2;

    return input;
}

तो एक परिभाषा दूसरे से बेहतर नहीं है। लेकिन आमतौर पर आप एक साधारण रिटर्न का उपयोग करना चाहते हैं, जब तक कि आपके पास उदाहरण के लिए उपरोक्त स्थिति न हो।

EDIT: यह एक नमूना है जिसके कारण कीवर्ड मौजूद है। उपरोक्त किसी भी तरह से सबसे अच्छा अभ्यास नहीं माना जाता है।


2
मैं इससे असहमत हूं, आप 4 इन्टस के साथ डेटा स्ट्रक्चर क्यों नहीं लौटाएंगे? यह वाकई भ्रामक है।
चाड ग्रांट

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

2
मैं @ क्लॉड से सहमत हूं। सिर्फ इसलिए कि यह सबसे अच्छा तरीका नहीं है इसका मतलब यह नहीं है कि इसका अस्तित्व नहीं होना चाहिए।
सेरेब्रस

वैसे कोड एक के लिए भी संकलित नहीं होगा ... और यह कम से कम उल्लेख करना चाहिए कि इसे बुरा अभ्यास माना जाता है / पसंदीदा नहीं।
चाड ग्रांट

1
यह संकलन नहीं होगा? और यही वजह है कि? यह नमूना सिर्फ सही संकलन कर सकता है। और कृपया, मैं इस बात का एक नमूना दे रहा हूं कि क्यों एक विशेष वाक्यविन्यास / कीवर्ड मौजूद है, सर्वोत्तम प्रथाओं में कोई सबक नहीं।
पाइरोस्कुलस

23

आपको आम तौर पर एक आउट परम पर एक वापसी मूल्य पसंद करना चाहिए। यदि आप अपने आप को 2 चीजें करने की आवश्यकता वाले कोड लिख रहे हैं तो आउटकम एक आवश्यक बुराई है। इसका एक अच्छा उदाहरण है ट्राइ पैटर्न (जैसे Int32.TryParse)।

आइए विचार करें कि आपके दो तरीकों के कॉलर को क्या करना होगा। पहले उदाहरण के लिए मैं यह लिख सकता हूं ...

int foo = GetValue();

ध्यान दें कि मैं एक चर घोषित कर सकता हूं और इसे एक पंक्ति में आपकी विधि द्वारा निर्दिष्ट कर सकता हूं। 2nd उदाहरण के लिए यह इस तरह दिखता है ...

int foo;
GetValue(out foo);

अब मैं अपने वेरिएबल को सामने घोषित करने और दो लाइनों पर अपना कोड लिखने के लिए मजबूर हूं।

अपडेट करें

इस प्रकार के प्रश्न पूछने पर देखने के लिए एक अच्छी जगह .NET फ्रेमवर्क डिज़ाइन दिशानिर्देश है। यदि आपके पास पुस्तक संस्करण है, तो आप इस विषय पर एंडर्स हेजेल्सबर्ग और अन्य द्वारा एनोटेशन देख सकते हैं (पृष्ठ 184-185) लेकिन ऑनलाइन संस्करण यहाँ है ...

http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

यदि आप एक एपीआई से दो चीजों को वापस करने की जरूरत महसूस करते हैं, तो उन्हें एक संरचना / कक्षा में लपेटना एक आउट परम से बेहतर होगा।


महान जवाब, विशेष रूप से TryParse, एक (आम) फ़ंक्शन का संदर्भ जो डेवलपर्स को (असामान्य) बाहर चर का उपयोग करने के लिए मजबूर करता है।
सेरेब्रस

12

एक outपरम का उपयोग करने का एक कारण है जो पहले से ही उल्लेख नहीं किया गया है: कॉलिंग विधि इसे प्राप्त करने के लिए बाध्य है। यदि आपका तरीका एक मान उत्पन्न करता है जिसे कॉलर को नहीं छोड़ना चाहिए, तो यह outकॉल करने वाले को विशेष रूप से स्वीकार करने के लिए मजबूर करता है:

 Method1();  // Return values can be discard quite easily, even accidentally

 int  resultCode;
 Method2(out resultCode);  // Out params are a little harder to ignore

बेशक कॉलर अभी भी एक परम में मूल्य की अनदेखी कर सकता है out, लेकिन आपने इस पर उनका ध्यान आकर्षित किया है।

यह एक दुर्लभ आवश्यकता है; अधिक बार, आपको एक वास्तविक समस्या के लिए एक अपवाद का उपयोग करना चाहिए या "FYI" के लिए राज्य की जानकारी के साथ एक वस्तु वापस करना चाहिए, लेकिन ऐसी परिस्थितियां हो सकती हैं जहां यह महत्वपूर्ण है।


8

यह मुख्य रूप से वरीयता है

मुझे रिटर्न पसंद है और अगर आपके पास कई रिटर्न हैं तो आप उन्हें रिजल्ट डीटीओ में लपेट सकते हैं

public class Result{
  public Person Person {get;set;}
  public int Sum {get;set;}
}

5

आपके पास केवल एक वापसी मान हो सकता है जबकि आपके पास कई आउट पैरामीटर हो सकते हैं।

आपको केवल उन मामलों में मापदंडों पर विचार करने की आवश्यकता है।

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


5

आपको लगभग हमेशा रिटर्न वैल्यू का उपयोग करना चाहिए। ' out' पैरामीटर बहुत सारे एपीआई, संरचना, आदि के लिए थोड़ा घर्षण पैदा करते हैं।

सबसे उल्लेखनीय अपवाद जो मन को भाता है, जब आप कई मान लौटना चाहते हैं (.Net फ्रेमवर्क में 4.0 तक ट्यूपल नहीं हैं), जैसे कि TryParseपैटर्न के साथ ।


यकीन नहीं है कि अगर यह एक अच्छा अभ्यास है, लेकिन Arraylist भी कई मूल्यों को वापस करने के लिए इस्तेमाल किया जा सकता है।
BA

@ आईबीए यह एक अच्छा अभ्यास नहीं है, अन्य उपयोगकर्ताओं को यह नहीं पता होगा कि इस Arraylist में क्या है, या वे किस स्थिति में हैं। उदाहरण के लिए मैं पढ़ी गई बाइट्स की राशि और मूल्य भी वापस करना चाहता हूं। बाहर या tuples जो नाम दिए गए हैं बेहतर होगा। ArrayList, या कोई अन्य सूची केवल तभी उपयोगी होगी जब आप चीजों का एक संघटन वापस करना चाहते हैं, उदाहरण के लिए व्यक्तियों की सूची।
sLw

2

मैं इस सरल उदाहरण में उन दोनों के बजाय निम्नलिखित को प्राथमिकता दूंगा।

public int Value
{
    get;
    private set;
}

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


2

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


2

इसके अतिरिक्त, वापसी मूल्य अतुल्यकालिक डिजाइन प्रतिमानों के साथ संगत हैं।

यदि आप रेफरी या आउट मापदंडों का उपयोग करते हैं, तो आप "async" फ़ंक्शन को नामित नहीं कर सकते।

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


"Async" पदनाम पर महान बिंदु। सोचा था कि किसी और ने उल्लेख किया होगा। चैनिंग - एक अभिव्यक्ति के रूप में रिटर्न वैल्यू (वास्तव में फ़ंक्शन स्वयं) का उपयोग करने के साथ-साथ एक अन्य कुंजी है। यह वास्तव में केवल एक प्रक्रिया से सामान वापस पाने के बारे में विचार करने के बीच का अंतर है ("बकेट" - टपल / क्लास / स्ट्रक्चर चर्चा) और इस प्रक्रिया को एक अभिव्यक्ति की तरह व्यवहार करना जो एक ही मूल्य के लिए प्रतिस्थापित किया जा सकता है (उपयोगिता का) कार्य स्वयं करें, क्योंकि यह केवल 1 मान देता है)।
user1172173

1

दोनों का एक अलग उद्देश्य है और संकलक द्वारा एक जैसा व्यवहार नहीं किया जाता है। यदि आपकी विधि को एक मूल्य वापस करने की आवश्यकता है, तो आपको रिटर्न का उपयोग करना होगा। आउट का उपयोग किया जाता है जहां आपकी विधि को कई मानों को वापस करने की आवश्यकता होती है।

यदि आप रिटर्न का उपयोग करते हैं, तो डेटा को पहले स्टैक के तरीकों और फिर कॉलिंग मेथड में लिखा जाता है। जबकि बाहर के मामले में, यह सीधे कॉलिंग विधियों स्टैक को लिखा जाता है। यकीन नहीं होता अगर कोई और मतभेद हैं।


तरीके ढेर हो गए? मैं कोई c # विशेषज्ञ नहीं हूं, लेकिन x86 केवल एक स्टैक प्रति थ्रेड का समर्थन करता है। विधि के "फ्रेम" को वापसी के दौरान निपटाया जाता है, और यदि कोई संदर्भ ख़ुशी में बदल जाता है तो डीलक्लोकेट किए गए स्टैक को फिर से लिखा जा सकता है। सी में सभी रिटर्न मान रजिस्ट्री ईआरएक्स में जाते हैं। यदि आप वस्तुओं / संरचनाओं को वापस करना पसंद करते हैं, तो उन्हें ढेर में आवंटित करने की आवश्यकता होती है और सूचक को ईएक्सएक्स में डाल दिया जाएगा।
स्टीफन लुंडस्ट्रोम

1

जैसा कि अन्य लोगों ने कहा है: रिटर्न वैल्यू, न कि आउट परम।

क्या मैं आपको पुस्तक "फ्रेमवर्क डिज़ाइन दिशानिर्देश" (दूसरा संस्करण) सुझा सकता हूं? पृष्ठ 184-185 में परम से बचने के कारणों को शामिल किया गया है। पूरी पुस्तक आपको सभी प्रकार के .NET कोडिंग मुद्दों पर सही दिशा में आगे बढ़ाएगी।

फ्रेमवर्क डिज़ाइन दिशानिर्देशों के साथ संबद्ध स्थिर विश्लेषण उपकरण, FxCop का उपयोग है। आपको यह माइक्रोसॉफ्ट की साइटों पर मुफ्त डाउनलोड के रूप में मिलेगा। इसे अपने संकलित कोड पर चलाएं और देखें कि यह क्या कहता है। अगर यह सैकड़ों और सैकड़ों चीजों के बारे में शिकायत करता है ... घबराओ मत! शांतिपूर्वक और ध्यान से देखें कि यह प्रत्येक मामले के बारे में क्या कहता है। ASAP चीजों को ठीक करने के लिए जल्दी मत करो। इससे जानिए कि यह आपको क्या बता रहा है। आपको मालकियत के लिए सड़क पर रखा जाएगा।


1

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

var result = DoThing();
if (result.Success)
{
    result = DoOtherThing()
    if (result.Success)
    {
        result = DoFinalThing()
        if (result.Success)
        {
            success = true;
        }
    }
}

बनाम:

var result;
if (DoThing(out result))
{
    if (DoOtherThing(out result))
    {
        if (DoFinalThing(out result))
        {
            success = true;
        }
    }
}

1

कोई वास्तविक अंतर नहीं है। बाहर पैरामीटर C # में हैं ताकि विधि अधिक वापस आ सके, एक मूल्य है।

हालाँकि कुछ मामूली अंतर हैं, लेकिन उनमें से कुछ वास्तव में महत्वपूर्ण हैं:

पैरामीटर का उपयोग करना आपको दो लाइनों का उपयोग करने के लिए लागू करेगा जैसे:

int n;
GetValue(n);

वापसी मूल्य का उपयोग करते समय आप इसे एक पंक्ति में करेंगे:

int n = GetValue();

एक और अंतर (केवल मान प्रकार के लिए सही है और केवल अगर C # फ़ंक्शन को इनलाइन नहीं करता है) यह है कि रिटर्न वैल्यू का उपयोग करते समय फ़ंक्शन को वापस करते समय मूल्य की एक प्रति आवश्यक रूप से बनाई जाएगी, जबकि OUT पैरामीटर का उपयोग करना आवश्यक नहीं होगा।


0

जब आप किसी वस्तु को वापस करने की कोशिश कर रहे हों, तो वह अधिक उपयोगी होती है।

उदाहरण

public BookList Find(string key)
{
   BookList book; //BookList is a model class
   _books.TryGetValue(key, out book) //_books is a concurrent dictionary
                                     //TryGetValue gets an item with matching key and returns it into book.
   return book;
}

0

रिटर्न वैल्यू वह सामान्य मूल्य है जो आपकी विधि द्वारा लौटाया जाता है।

कहाँ के रूप में बाहर पैरामीटर, अच्छी तरह से बाहर और रेफरी सी # के 2 कुंजी शब्द हैं वे के रूप में चर पारित करने के लिए अनुमति देने के संदर्भ

Ref और out के बीच बड़ा अंतर यह है कि Ref को पहले और बाहर नहीं शुरू किया जाना चाहिए


-2

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

मेरा मानना ​​है कि यह वस्तु-उन्मुख प्रोग्रामिंग भाषाओं को उनके मूल्य-वापसी प्रक्रियाओं (वीआरपी) के लिए बेहतर बनाता है जो निर्धारक और शुद्ध हों।

'वीआरपी' एक फ़ंक्शन के लिए आधुनिक शैक्षणिक नाम है जिसे एक अभिव्यक्ति के हिस्से के रूप में कहा जाता है, और इसमें एक वापसी मूल्य होता है जो अभिव्यक्ति के मूल्यांकन के दौरान कॉल को प्रतिस्थापित करता है। जैसे कि एक स्टेटमेंट में, जैसे x = 1 + f(y)फ़ंक्शन fVRP के रूप में कार्य कर रहा है।

'नियतात्मक' का अर्थ है कि फ़ंक्शन का परिणाम केवल उसके मापदंडों के मूल्यों पर निर्भर करता है। यदि आप इसे फिर से उसी पैरामीटर मानों के साथ कहते हैं, तो आपको समान परिणाम प्राप्त होना निश्चित है।

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

इस प्रकार, यदि, सी # में, अपने कार्य नहीं नियतात्मक और शुद्ध है, मैं कहता हूँ आप इसे एक बनाना चाहिए voidसमारोह (दूसरे शब्दों में, नहीं एक VRP), और किसी भी कीमत यह वापसी करने की जरूरत है या तो एक में वापस आ जाना चाहिए outया एक refपैरामीटर।

उदाहरण के लिए, यदि आपके पास डेटाबेस तालिका से कुछ पंक्तियों को हटाने का कोई कार्य है, और आप चाहते हैं कि यह हटाई गई पंक्तियों की संख्या लौटाए, तो आपको इसे कुछ इस तरह घोषित करना चाहिए:

public void DeleteBasketItems(BasketItemCategory category, out int count);

यदि आप कभी-कभी इस फ़ंक्शन को कॉल करना चाहते हैं count, लेकिन नहीं मिलता है , तो आप हमेशा ओवरलोडिंग की घोषणा कर सकते हैं।

आप जानना चाह सकते हैं कि यह शैली ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग को बेहतर क्यों बनाती है। मोटे तौर पर, यह प्रोग्रामिंग की एक शैली में फिट बैठता है, जो (थोड़ा असंभव) को 'प्रक्रियात्मक प्रोग्रामिंग' कहा जा सकता है, और यह एक प्रक्रियात्मक प्रोग्रामिंग शैली है जो ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग को बेहतर ढंग से फिट करता है।

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

प्रक्रियात्मक प्रोग्रामिंग का नकारात्मक पक्ष यह है कि, क्योंकि आप सभी जगह मनमाने कोड निष्पादित कर सकते हैं, आप वैश्विक चर और दुष्प्रभावों के माध्यम से कुछ बहुत ही अप्रिय और बग-कमजोर बातचीत प्राप्त कर सकते हैं।

इसलिए, बस, अपने कोड को पढ़ने वाले किसी व्यक्ति को यह संकेत देना अच्छा है कि एक फ़ंक्शन इसे गैर-मूल्य रिटर्न करके बना सकता है।


> यदि आप कभी-कभी इस फ़ंक्शन को कॉल करना चाहते हैं, लेकिन गिनती प्राप्त नहीं करते हैं, तो आप हमेशा ओवरलोडिंग की घोषणा कर सकते हैं। सी # संस्करण 7 में (मुझे लगता है) और बाद में, आप _आउट पैरामीटर को अनदेखा करने के लिए त्याग चिह्न का उपयोग कर सकते हैं , जैसे: DeleteBasketItems (श्रेणी, आउट _);
डिबेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.