2015-03-13 9 views
7

एमएसडीएन के अनुसार, यदि सभी सरणी संदर्भ प्रकार हैं, तो दिए गए नमूना कोड में, t2 का नया मान t1 में परिवर्तन को प्रतिबिंबित नहीं करता है?सी # में ऐरे संदर्भ प्रकार हैं, वे मूल्य प्रकार के रूप में क्यों कार्य करते हैं?

string[] data = new[] { "One", "Two" }; 

var t1 = data[0]; 

Console.WriteLine(t1); 

var t2 = t1; 
t2 = "Three"; //assigning the new value, and this should reflect in t1 

Console.WriteLine(t2); 
Console.WriteLine(t1); // this should print 'Three', but it prints 'One' 

Console.Read(); 

enter image description here

http://msdn.microsoft.com/en-us/magazine/cc301755.aspx

सरणी तंत्र है कि आप एक एक संग्रह के रूप में कई मदों के इलाज के लिए अनुमति देते हैं। माइक्रोसॉफ्ट® .NET कॉमन लैंग्वेज रनटाइम (सीएलआर) एकल-आयामी सरणी, बहुआयामी सरणी, और जंजीर सरणी (सरणी के सरणी) का समर्थन करता है। सभी सरणी प्रकार निश्चित रूप से System.Array से व्युत्पन्न हैं, जो स्वयं सिस्टम.ऑब्जेक्ट से प्राप्त किए गए हैं। इसका मतलब है कि सभी सरणी हमेशा संदर्भ प्रकार होते हैं जो प्रबंधित ढेर पर आवंटित हैं, और आपके ऐप के चर में सरणी के संदर्भ में है और सरणी स्वयं नहीं है।

+3

मेरे लिए यह लगता है कि आप बस 'एक और स्मृति स्थान पर t2' बिंदु दे रहे हैं। –

+5

आप किसी संदर्भ/फ़ील्ड की सामग्री को संदर्भित करने वाले डेटा को म्यूट करने के साथ भ्रमित कर रहे हैं। – CodesInChaos

+0

सरणी स्वयं निश्चित रूप से संदर्भ-प्रकार है, लेकिन यह इसके निहित तत्वों के लिए गिनती नहीं है। वे संदर्भ-प्रकार (कक्षा-वस्तुओं के मामले में), या मूल्य-प्रकार हो सकते हैं। – HimBromBeere

उत्तर

18

एक तस्वीर एक हजार शब्दों के बराबर है, इसलिए यहाँ क्या हो रहा है यह है:

Before and After

"Three"t2 करने का काम का असर है कि काम से पहले t1 और t2 संदर्भित है एक ही वस्तु, लेकिन असाइनमेंट के बाद वे विभिन्न वस्तुओं का संदर्भ देते हैं। यहां कुछ और नहीं चल रहा है।

यदि आपके पास म्यूटेबल ऑब्जेक्ट्स की एक सरणी थी, तो स्थिति अलग-अलग होती, और उनके संदर्भों को सेट करने के बजाय उनके मूल्य का उपयोग किया जाता है। उदाहरण के लिए, StringBuilder ऑब्जेक्ट्स की सरणी के साथ तारों की सरणी को प्रतिस्थापित करने और असाइनमेंट के बजाय t2.Replace("Two", "Three") पर कॉल करने की कल्पना करें। अब प्रभाव, अलग हो क्योंकि t1, t2, और data[0] एक ही वस्तु की ओर इशारा करते किया जाएगा।

+2

1000 शब्दों की कोई आवश्यकता नहीं है, केवल इन: ओपी के कोड में एकमात्र सरणी 'डेटा' है, जिसका उपयोग कभी भी नहीं किया जाता है, इसके 0 वें तत्व को खींचने के अलावा। –

7

आपके प्रश्न के पास सरणी से कोई लेना देना नहीं है। चूंकि आपका data[0]string है - और यह एक संदर्भ प्रकार है- यह मान One है, आप इसे कभी भी मूल्य नहीं बदलते हैं। आपने अभी एक और स्ट्रिंग संदर्भ बनाया है जिसे t2 कहा जाता है और t1 संदर्भ के साथ उसी ऑब्जेक्ट पर बिंदु सेट करें। इस संदर्भ ऑब्जेक्ट को "Three" पर बदलने के बाद, लेकिन यह t1 पर संदर्भित नहीं करेगा।

चलो अपने कोड को लाइन से लाइन पर देखें;

var t1 = data[0]; 

इस लाइन के साथ आप t1 के रूप में एक स्ट्रिंग संदर्भ बनाया है और इस "One" वस्तु को इंगित करता है।

var t2 = t1; 
इस लाइन के साथ

, आप t2 रूप में एक नया स्ट्रिंग संदर्भ बना सकते हैं और इस t1 जो है "One"

t2 = "Three"; 

इस लाइन के साथ साथ एक ही वस्तु के लिए अंक, आपके द्वारा बनाए गए एक स्ट्रिंग वस्तु बुलाया "Three" और अपने t2 इस ऑब्जेक्ट का संदर्भ है। यह ऑब्जेक्ट और पर इंगित नहीं करता है। लेकिन यह t1 संदर्भ पर प्रभाव नहीं है। यह अभी भी अंक "One" ऑब्जेक्ट पर है।

है यही कारण है कि

Console.WriteLine(t2); 
Console.WriteLine(t1); 

प्रिंट

Three 
One 
0

लेखन t2 = "Three" t1 का मूल्य परिवर्तन नहीं करेगा क्योंकि प्रकार संदर्भ प्रकार के होते हैं, ताकि वे अपने डेटा को "बिंदु"। t2 को असाइन करके आप इसे किसी अन्य संदर्भ के लिए कह रहे हैं।

इसी तरह, जब आपने t2 = t1 लिखा था तो आप को t1 के समान संदर्भ देने के लिए बस बता रहे हैं। t2 पर भविष्य के कार्यवाही सिर्फ इसे कुछ और संदर्भित करेंगे।

कुछ भाषाओं, सी ++ की तरह, यदि आप किसी अन्य चर के लिए एक संदर्भ स्टोर करने के लिए के लिए ताकि जब आप संदर्भ बदल आप वास्तव में बदल क्या अन्य चर रहा है की क्षमता है।

7

स्ट्रिंग्स भी प्रकार के संदर्भ कर रहे हैं। तो अगर आप लिखें:

var t1 = data[0]; 

आप घोषणा की है एक नया वेरिएबल t1 कि data[0] रूप में एक ही स्ट्रिंग के लिए संदर्भ। इस के बाद आप लिखते हैं:

var t2 = t1; 

अब आप t1 रूप में एक ही स्ट्रिंग के लिए एक नया वेरिएबल t2 कि संदर्भ की है। data[0], t1 और t2: अब आप ढेर पर एक String वस्तु है, और इस वस्तु को तीन संदर्भों की है।

तो फिर तुम लिखें:

t2 = "Three"; 

इस बयान के बाद, t2 अंक मूल्य "Three" साथ ढेर में antoher स्ट्रिंग के लिए। हालांकि, data[0] और t1 अभी भी वही मूल स्ट्रिंग को इंगित करते हैं।

0

इस कार्यक्रम वास्तव में आप उम्मीद कर के रूप में व्यवहार।

void Main() 
{ 
    abc[] data = new[] { new abc(){i=1}, new abc(){i=2} }; 

var t1 = data[0]; 
var t2 = t1; 
// here is the difference 
// t2 is still pointing to its old location 
// but i will point a new position. 
t2.i = 5 ; //assigning the new value to i 
// but t2 still pointing to t1 
//all will be identical now. 
Console.WriteLine(t2); 
Console.WriteLine(t1); 
Console.WriteLine(data[0]); 


    // repeating like you. 
    t2 = new abc() {i=444}; 
//now you will see t2 is different form t1. because 
// now t2 pointing to a new object instead of t1. 
Console.WriteLine(t2); 
Console.WriteLine(t1); 


} 

public class abc{ 
    public int i ; 
} 
-1

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

// सरणी संदर्भ चर निर्दिष्ट करना।

 using System; class AssignARef { 
    static void Main() 
    { 
int i; 
    int[] nums1 = new int[10]; 
    int[] nums2 = new int[10]; 
    for(i=0; i < 10; i++) 
    nums1[i] = i; 
    for(i=0; i < 10; i++) 
    nums2[i] = -i; 
    Console.Write("Here is nums1: "); 
    for(i=0; i < 10; i++) 
    Console.Write(nums1[i] + " "); 
    Console.WriteLine(); 
    Console.Write("Here is nums2: "); 
    for(i=0; i < 10; i++) 
    Console.Write(nums2[i] + " "); 
    Console.WriteLine(); nums2 = nums1; // now nums2 refers to nums1 
    Console.Write("Here is nums2 after assignment: "); 
    for(i=0; i < 10; i++) 
    Console.Write(nums2[i] + " "); 
    Console.WriteLine(); // Next, operate on nums1 array through nums2. 
    nums2[3] = 99; 
    Console.Write("Here is nums1 after change through nums2: "); 
    for(i=0; i < 10; i++) 
    Console.Write(nums1[i] + " "); 
    Console.WriteLine(); 

} 
} 

ओ/p

Here is nums1: 0 1 2 3 4 5 6 7 8 9 
Here is nums2: 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 
Here is nums2 after assignment: 0 1 2 3 4 5 6 7 8 9 
Here is nums1 after change through nums2: 0 1 2 99 4 5 6 7 8 9 
संबंधित मुद्दे