2012-05-24 3 views
6

मैं कक्षा में किसी फ़ंक्शन में डबल [] की एक सूची उत्तीर्ण कर रहा हूं, एक tempList का उपयोग करके फ़ंक्शन के भीतर मानों को संपादित कर रहा हूं, फिर संपादित मानों को वापस कर रहा हूं। लेकिन मूल सूची उत्तीर्ण की जा रही है जिसे मैं संपादित नहीं करना चाहता हूं, जिसे वे tempList से मेल खाने के लिए संपादित नहीं करना चाहते हैं।संपादन सूची के साथ समस्या <double[]> सी #

यहां कोड है।

List<double[]> newList = new List<double[](); 
newList = myClass.myFunction(value, originalList); 

// myClass 
... 

// myFunction 
public List<double[]> myFunction(int value, List<double[]> myList) 
{ 
    List<double[]> tempList = new List<double[]>(); 
    for (int i = 0; i < myList).Count; i++) 
    { 
     tempList.Add(myList[i]); 
    } 


    // Do stuff to edit tempList 

    return tempList; 
} 
+0

क्या वास्तव में अपने प्रश्न है, आप क्या करना चाहते हैं? आप मूल सूची संपादित कर सकते हैं, आपको एक नया निर्माण करने की आवश्यकता नहीं है। –

उत्तर

4

ध्यान रखें कि सरणियों संदर्भ प्रकार हैं। जब आप tempList पर कोई सरणी जोड़ते हैं, तो केवल सरणी का संदर्भ जोड़ा जा रहा है, ताकि myList और tempList दोनों एक ही double[] ऑब्जेक्ट्स का संदर्भ लें।

इसके बजाय, आप सरणियों का क्लोन बनाने की जरूरत है:

for (int i = 0; i < myList.Count; i++) 
{ 
    tempList.Add((double[])myList[i].Clone()); 
} 
+0

हां, लेकिन कोड पहली जगह में डोडी दिखता है। एक सरणी क्लोन करना शायद ही कभी सही काम है। –

0

समस्या आप कर रहे हैं double[] है एक संदर्भ प्रकार, नहीं एक मान प्रकार है, इसलिए जब आप इसे अपने tempList को जोड़ रहे हैं, आप मूल ऑब्जेक्ट का संदर्भ जोड़ रहे हैं, न कि एक नई वस्तु। tempList पर जोड़ने से पहले आपको वास्तव में एक नया double[] बनाने की आवश्यकता है ताकि आप मूल ऑब्जेक्ट पर काम नहीं कर रहे हों।

मान लीजिए कि आप LINQ का उपयोग कर सकते हैं, आपको लूप की आवश्यकता नहीं है। आप कुछ ऐसा कर सकते हैं:

var tempList = myList.Select(x => x.ToArray()).ToList(); 
0

ऐसा इसलिए है क्योंकि संग्रह/संदर्भ प्रकार संदर्भ द्वारा पारित किए जाते हैं। (असल में होल्डिंग वैरिएबल मान द्वारा पारित किया जाता है, लेकिन सभी चर समान संदर्भ को इंगित करते हैं)।

विस्तार स्पष्टीकरण के लिए, पढ़ने के this SO Answer

यदि आप चाहते हैं कि मेरे समारोह में संशोधन मूल संग्रह में प्रतिबिंबित नहीं करता है, आप कॉपी/यह क्लोन और फिर myFunction को पारित करने के लिए की है।

उदाहरण

newList = myClass.myFunction(value, (List<double>)originalList.Clone()); 
1

एक सरणी, here double[], एक संदर्भ प्रकार है, तो लाइन

tempList.Add(myList[i]); 

मूल सरणी के लिए एक संदर्भ जोड़ रहा है है। फिर जब आप tempList संपादित करते हैं तो आप मूल सरणी संपादित कर रहे हैं। इस तरह की एक कॉपी बनाएं:

tempList.Add(myList[i].ToArray()); 
0
tempList.Add(myList[i]); 

मतलब है कि आप सूचकांक मैं अस्थायी सूची पर डबल [] वस्तु के संदर्भ में जोड़ सकते हैं। इसलिए, यदि आप उस ऑब्जेक्ट के मान को संपादित करते हैं, तो आपको दोनों सूचियों पर संभावनाएं मिलेंगी।

अगर आप किसी अन्य क्लोन सूचियों कि एक दूसरे को प्रभावित नहीं करेगा करना चाहते हैं कि क्या करना होगा:

List<double[]> tempList = new List<double[]>(); 
for (int i = 0; i < myList).Count; i++) 
{ 
    double[] originalListItem = myList[i]; 

    // the most important step here!!! - clone the originalListItem to clonedListItem 

    tempList.Add(clonedListItem); 
} 


// Do stuff to edit tempList 

return tempList; 
1

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

foreach (double[] item in myList) 
{ 
    double[] copy = new double[item.Length]; 
    Array.Copy(item, copy); 
    templist.Add(copy); 
} 
0

आप नई सूची में डबल [] संदर्भ की प्रतिलिपि बना रहे हैं, यह एक उथली प्रति है। आपको मूल गहराई को बदलने के बिना अस्थायी प्रतिलिपि बनाने और अस्थायी सरणी को संपादित करने के लिए नए डबल एरे बनाने की आवश्यकता है।

0

आप tempList में सरणी के संदर्भों को संदर्भित कर रहे हैं, सरणी की प्रति नहीं। तो यदि आप tempList में कोई मान बदलते हैं, तो आप मूल सरणी बदल रहे हैं।

इस कोड को बेहतर काम करेगा:

for (int i = 0; i < myList.Count; i++) 
    { 
     var copy = new Double[myList[i].Length]; 
     Array.Copy(myList[i], copy, myList[i].Length); 
     tempList.Add(copy); 
    }