2011-02-05 8 views
16

क्या अंतर है? मैं हमेशा ByVal का उपयोग करता हूं, लेकिन, मुझे वास्तव में कोई अच्छा विचार नहीं है कि मुझे कब और कब नहीं चाहिए ...ByVal और ByRef के बीच अंतर?

+0

95% + जब आप बायवेल चाहते हैं, तो संभवतः आप सभी के साथ सही विकल्प बना रहे हैं :) लेकिन इसके बारे में जानने के लिए पहल के लिए +1। –

+1

प्रस्तावना: मैं एक वीबी प्रोग्रामर नहीं हूं। यदि यह सी या सी ++ जैसा कुछ भी है, तो ऑब्जेक्ट प्रतिलिपि बनाने के लिए महंगा होने पर ByVal गुजरना महंगा हो सकता है। यदि आप जानते हैं कि आप इसे संशोधित नहीं कर रहे हैं, तो ByRef तेज़ हो सकता है और फ़ंक्शन वही व्यवहार करेगा। –

+0

मैंने नीचे एक ही चीज़ पर टिप्पणी की, लेकिन बस मामले में ... ByVal * ऑब्जेक्ट की एक प्रति नहीं बनाते (मूल्य प्रकार चर के अपवाद के साथ)। यह एक ही वस्तु के लिए एक नया संदर्भ बनाता है। आप सही हैं कि ByRef * तेज हो सकता है (एक नया संदर्भ बनाने की आवश्यकता नहीं है) लेकिन अंतर सबसे अच्छा होगा। – Smudge202

उत्तर

10

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

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

तो, वास्तव में, आपको आमतौर पर वैरिएबल को मान के रूप में पास करना चाहिए। अगर आपको ऐसा करने की स्पष्ट आवश्यकता है तो केवल संदर्भ के रूप में पास करें।

+6

मुझे लगता है कि यह * बहुत * महत्वपूर्ण है कि ध्यान दें कि मूल वस्तु, जब पारगमन पारित किया जा सकता है, बदला नहीं जा सकता है, यह बच्चे के सदस्य – Smudge202

+1

वास्तव में, Smudge202 हो सकते हैं, यह महत्वपूर्ण है ... आप ऑब्जेक्ट सदस्यों को संशोधित कर सकते हैं (या, दूसरे में शब्द, आप ऑब्जेक्ट को म्यूट कर सकते हैं)। आप जो म्यूटेट नहीं कर सकते वह संदर्भ है, जिसका अर्थ है कि आप ऑब्जेक्ट को किसी ऑब्जेक्ट या नल के साथ प्रतिस्थापित नहीं कर सकते हैं। आपके उत्तर को स्पष्ट करने के लिए –

+0

+1। साथ ही, * मेरी रोचक * बिंदु – Smudge202

4

ByRef एक दूसरे रिटर्न मूल्य की तरह है। यह ऑब्जेक्ट के बजाए फ़ंक्शन में ऑब्जेक्ट का संदर्भ देता है। यदि आप फ़ंक्शन में ByRef पैरामीटर का मान बदलते हैं, तो फ़ंक्शन समाप्त होने के बाद आप उन परिवर्तनों को देखेंगे। यदि वह पर्याप्त स्पष्ट नहीं था, read this और this

10

ByRef = आप अपने दोस्त को अपना टर्म पेपर (मूल) देते हैं, वह इसे चिह्नित करता है और इसे आपके पास वापस कर सकता है।

ByVal = आप पेम शब्द की एक प्रतिलिपि देते हैं और वह आपको अपने परिवर्तन वापस देता है लेकिन आपको उन्हें अपने मूल में वापस रखना होगा।

जितना आसान मैं इसे बना सकता हूं।

बायफ का उपयोग क्यों करें:
ByRef आपके द्वारा पारित ऑब्जेक्ट पर पॉइंटर को पास कर देगा। यदि आप एक ही मेमोरी स्पेस में हैं, तो इसका अर्थ केवल 'शब्द' को ऑब्जेक्ट नहीं करना है। जिस विधि को आप पास कर रहे हैं वह मूल वस्तु में परिवर्तन कर सकता है, और उन्हें मूल वस्तु में होने के कारण उन्हें वापस पास करने की आवश्यकता नहीं है। बड़े डेटा को तेजी से पास करने के लिए उपयोगी। आप बाय्रफ का उपयोग एसयूबी के उपयोग की अनुमति देने के लिए भी कर सकते हैं, फिर एक फंक्शन (वीबी में) क्योंकि इसे ऑब्जेक्ट को वापस करने की आवश्यकता नहीं है।

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

+2

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

+0

मेरा मानना ​​है कि आप सही हैं, लेकिन सही नहीं :) वैल द्वारा, नई वस्तु में आपके द्वारा बुलाए जाने वाले प्रक्रिया का दायरा है, और प्रक्रिया के दायरे में पूरी तरह से और स्पष्ट रूप से संपादन योग्य है। एक बार प्रसंस्करण प्रक्रिया प्रक्रिया छोड़ देता है वस्तु वस्तु से बाहर हो जाती है और पुनर्नवीनीकरण (और unavalable) है। इसलिए यह वैल द्वारा उपयोग किए जाने वाले ऑब्जेक्ट की एक पूर्ण प्रतिलिपि बनाता है। रेफरी द्वारा ऑब्जेक्ट की ओर इशारा करते हुए, और ऑब्जेक्ट की कोई अतिरिक्त प्रति नहीं बनाई जाती है। –

+1

@TomVandeStouwe: आप गलत हैं। कोई नई वस्तु नहीं बनाई गई है। यह किसी भी विभिन्न तरीकों से आसानी से टेस्टेबल है (एक विशाल वस्तु का उपयोग करने से जो हैशकोड को देखने के लिए कई बार स्मृति में फिट नहीं होगा)। – jmoreno

5

मैं इस सवाल का काफी उत्तर दिया गया है पता है, लेकिन मैं सिर्फ निम्नलिखित जोड़ने के लिए ...

वस्तु आप एक समारोह को पारित ByRef/ByVal के अधीन है चाहता था, लेकिन, अगर उस वस्तु संदर्भ शामिल हैं अन्य वस्तुओं के लिए, उन्हें ByRef/ByVal के बावजूद बुलाए गए विधि द्वारा संशोधित किया जा सकता है। गरीब स्पष्टीकरण, मुझे पता है, एक बेहतर समझ के लिए नीचे दिए गए कोड देखें:

Public Sub Test() 
    Dim testCase As List(Of String) = GetNewList() 
    ByRefChange1(testCase) 
    'testCase = Nothing 
    testCase = GetNewList() 

    ByValChange1(testCase) 
    'testCase is unchanged 
    testCase = GetNewList() 

    ByRefChange2(testCase) 
    'testCase contains the element "ByRef Change 2" 
    testCase = GetNewList() 

    ByValChange2(testCase) 
    'testCase contains the element "ByVal Change 2" 

End Sub 

Public Function GetNewList() As List(Of String) 
    Dim result As List(Of String) = New List(Of String) 
    result.Add("Value A") 
    result.Add("Value B") 
    result.Add("Value C") 
    Return result 
End Function 

Public Sub ByRefChange1(ByRef aList As List(Of String)) 
    aList = Nothing 
End Sub 

Public Sub ByValChange1(ByVal aList As List(Of String)) 
    aList = Nothing 
End Sub 

Public Sub ByRefChange2(ByRef aList As List(Of String)) 
    aList.Add("ByRef Change 2") 
End Sub 

Public Sub ByValChange2(ByVal aList As List(Of String)) 
    aList.Add("ByVal Change 2") 
End Sub 

संपादित करें:

इसके अलावा, पर विचार करता है, तो इस समारोह बुलाया गया था:

Public Sub ByValChange3(ByVal aList As List(Of String)) 
    aList.Add("ByVal Change 3") 
    aList = New List(Of String) 
    aList.Add("ByVal Change 4") 
End Sub 

क्या इस मामले में क्या होता है " ByVal Change 3 "को कॉलर्स सूची में जोड़ा गया है, लेकिन उस बिंदु पर आप निर्दिष्ट करते हैं कि" aist = new list "आप फिर नए संदर्भ को इंगित कर रहे हैं, एक नई ऑब्जेक्ट पर, और कॉलर्स सूची से अलग हो जाएं। दोनों सामान्य ज्ञान और आपको एक दिन बाहर पकड़ सकता है, इसलिए कुछ ध्यान में रखना। पिछले उप "byval" और नहीं "ByRef" होना चाहिए:

0

मैं इससे आपके प्रश्न का

Sub last_column_process() 
Dim last_column As Integer 

last_column = 234 
MsgBox last_column 

trying_byref x:=last_column 
MsgBox last_column 

trying_byval v:=last_column 
MsgBox last_column 

End Sub 

Sub trying_byref(ByRef x) 
x = 345 
End Sub 

Sub trying_byval(ByRef v) 
v = 555 
End Sub 
0

सोचो पिछले नमूना लिखने में कोई गलती हुई होगी उत्तर देता है उम्मीद है। :)

ने try_byval में एक संदेश बॉक्स भी जोड़ा ताकि आप समझ सकें कि क्या मतलब है।

Sub begin() 
Dim last_column As Integer 

last_column = 234 
MsgBox "Begin:" & last_column 

trying_byref x:=last_column 
MsgBox "byref:" & last_column 

trying_byval v:=last_column 
MsgBox "byval:" & last_column 
End Sub 

Sub trying_byref(ByRef x) 
x = 111 
End Sub 

Sub trying_byval(ByVal v) '<--not ByRef, that was in sub trying_byref. 
v = 222 
MsgBox "In Here:" & v 
End Sub 
0

ByRef, एक मूल्य के 2 पतों

होगा तो अगर एक्स = 80 (80 मूल्य है और एक्स पता है, तो उदाहरण चर के लिए y के साथ-साथ 80 हो सकता है, और इस तरह 80 पहुँचा जा सकता है एक्स और वाई द्वारा)

संबंधित मुद्दे