बीच क्या अंतर है System.Array.CopyTo()
और System.Array.Clone()
?
बीच क्या अंतर है System.Array.CopyTo()
और System.Array.Clone()
?
जवाबों:
क्लोन () विधि एक नई सरणी (एक उथले प्रतिलिपि) वस्तु मूल सरणी में सभी तत्वों वाली देता है। CopyTo () विधि प्रतियां एक और मौजूदा सरणी में तत्वों। दोनों उथली नकल करते हैं। उथली प्रतिलिपि का अर्थ है कि सामग्री (प्रत्येक सरणी तत्व) में मूल सरणी में तत्वों के समान ऑब्जेक्ट के संदर्भ होते हैं। एक गहरी प्रति (जो इन विधियों में से कोई भी प्रदर्शन नहीं करती है) प्रत्येक तत्व की वस्तु का एक नया उदाहरण बनाएगी, जिसके परिणामस्वरूप एक अलग, फिर भी समान वस्तु होगी।
तो अंतर हैं:
1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.
संपादित करें:
गलत उदाहरण निकालें।
numbersCopy
केवल सौंपे गए सरणी के लिए एक और संदर्भ है numbers
। यह विधि का उपयोग करने के समान नहीं हैCopyTo()
। यदि आप उपयोग करते हैं CopyTo()
, तो आपको अपने Clone()
उदाहरण के समान परिणाम प्राप्त होंगे । इसके अलावा, यह C # है - System.out.println
होना चाहिए Console.WriteLine
।
ToArray()
विधि किसी भी तरह से उथले-क्लोनिंग का एक बहुत सरल (और टाइप किया हुआ ) तरीका प्रदान करती है। चूंकि एरे वह IENumerable<T>
इस पर काम करता है।
अभी तक उल्लेखित एक अन्य अंतर यह नहीं है
Clone()
गंतव्य सरणी के साथ अभी तक मौजूद होने की आवश्यकता नहीं है क्योंकि एक नया खरोंच से बनाया गया है।CopyTo()
न केवल गंतव्य सरणी की जरूरत पहले से मौजूद हैं करता है, यह बड़ा पर्याप्त सूचकांक आप गंतव्य के रूप में निर्दिष्ट से स्रोत सरणी में सभी तत्वों को धारण करने के लिए की जरूरत है।जैसा कि कई अन्य उत्तरों में कहा गया है कि दोनों विधियाँ सरणी की उथली प्रतियां हैं । हालांकि ऐसे मतभेद और सिफारिशें हैं जिन्हें अभी तक संबोधित नहीं किया गया है और जिन्हें निम्नलिखित सूचियों में दर्शाया गया है।
के लक्षण System.Array.Clone
:
CopyTo
क्योंकि यह उपयोग करता है Object.MemberwiseClone
;के लक्षण System.Array.CopyTo
:
Clone
एक ही प्रकार के सरणी में कॉपी करते समय तेजी से होता है;Array.Copy
इनहेरिट करने की क्षमता है , जो सबसे उपयोगी है:
int[]
सरणी को एक में कॉपी करना object[]
;object[]
बॉक्सिंग के एक सरणी को एक में कॉपी int
करना int[]
;int[]
में कॉपी करना long[]
।Stream[]
सरणी को एक में कॉपी करना MemoryStream[]
(यदि स्रोत सरणी में कोई भी तत्व MemoryStream
अपवाद के लिए परिवर्तनीय नहीं है)।यह भी ध्यान रखें इन तरीकों का समर्थन करने के लिए उपलब्ध कराया जाता, ICloneable
और ICollection
, इसलिए यदि आप सरणी प्रकार आप उपयोग नहीं करना चाहिए की चर के साथ काम कर रहे हैं Clone
या CopyTo
और इसके बजाय का उपयोग Array.Copy
या Array.ConstrainedCopy
। विवश प्रतिलिपि ने आश्वासन दिया कि यदि प्रतिलिपि कार्रवाई पूर्ण नहीं हो सकती है, तो लक्ष्य सरणी स्थिति दूषित नहीं है।
.ToArray()
विधि का उपयोग कर सकते हैं । यह वैसे भी एक प्रतिलिपि बनाता है, और इसे किसी भी पर निष्पादित किया जा सकता है IEnumerable<>
, जिसमें सरणियाँ भी शामिल हैं। और इसके विपरीत .Clone()
, यह टाइप किया गया है, इसलिए कोई कास्टिंग की आवश्यकता नहीं है।
object[] myarray = new object[] { "one", 2, "three", 4, "really big number", 2324573984927361 };
//create shallow copy by CopyTo
//You have to instantiate your new array first
object[] myarray2 = new object[myarray.Length];
//but then you can specify how many members of original array you would like to copy
myarray.CopyTo(myarray2, 0);
//create shallow copy by Clone
object[] myarray1;
//here you don't need to instantiate array,
//but all elements of the original array will be copied
myarray1 = myarray.Clone() as object[];
//if not sure that we create a shalow copy lets test it
myarray[0] = 0;
Console.WriteLine(myarray[0]);// print 0
Console.WriteLine(myarray1[0]);//print "one"
Console.WriteLine(myarray2[0]);//print "one"
दोनों CopyTo () और क्लोन () उथले प्रतिलिपि बनाते हैं। क्लोन () विधि मूल सरणी का क्लोन बनाती है। यह एक सटीक लंबाई सरणी देता है।
दूसरी ओर, CopyTo () मूल सरणी से गंतव्य सरणी तक तत्वों को निर्दिष्ट गंतव्य सरणी सूचकांक पर शुरू करते हुए कॉपी करता है। ध्यान दें, यह पहले से मौजूद सरणी में तत्वों को जोड़ता है।
निम्न कोड पोस्टिंग के विपरीत कहेगा कि CopyTo () एक गहरी प्रतिलिपि बनाता है:
public class Test
{
public string s;
}
// Write Main() method and within it call test()
private void test()
{
Test[] array = new Test[1];
array[0] = new Test();
array[0].s = "ORIGINAL";
Test[] copy = new Test[1];
array.CopyTo(copy, 0);
// Next line displays "ORIGINAL"
MessageBox.Show("array[0].s = " + array[0].s);
copy[0].s = "CHANGED";
// Next line displays "CHANGED", showing that
// changing the copy also changes the original.
MessageBox.Show("array[0].s = " + array[0].s);
}
इसे मैं थोड़ा समझाता हूं। यदि ऐरे के तत्व संदर्भ प्रकार के हैं, तो पहले (शीर्ष) स्तर तक की प्रतिलिपि (दोनों क्लोन और) के लिए बनाई जाएगी। लेकिन निचले स्तर की नकल नहीं होती है। यदि हमें निचले स्तर की प्रति भी चाहिए, तो हमें यह स्पष्ट रूप से करना होगा। इसीलिए संदर्भ प्रकार के तत्वों की क्लोनिंग या प्रतिलिपि बनाने के बाद, क्लोन या कोपीड सरणी में प्रत्येक तत्व उसी मेमोरी स्थान को संदर्भित करता है, जो मूल सरणी में संबंधित तत्व द्वारा संदर्भित होता है। यह स्पष्ट रूप से इंगित करता है कि निचले स्तर के लिए कोई अलग उदाहरण नहीं बनाया गया है। और यदि ऐसा था तो कोपिड या क्लोन सरणी में किसी भी तत्व के मूल्य को बदलने से मूल सरणी के संबंधित तत्व में प्रभाव नहीं होगा।
मुझे लगता है कि मेरी व्याख्या संपूर्ण है लेकिन मुझे इसे समझने लायक कोई और रास्ता नहीं मिला।
Array.Clone()
जब int
संदर्भ के रूप में किसी विधि के लिए स्ट्रिंग या स्ट्रिंग की सरणी पास करें, तो तकनीकी रूप से गहरी प्रति प्रदर्शित होगी ।
उदाहरण के लिए
int[] numbers = new int[] { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
SortByAscending(numbers); // Sort the array in ascending order by clone the numbers array to local new array.
SortByDescending(numbers); // Same as Ascending order Clone
भले ही विधियाँ संख्याओं के प्रकार को क्रमबद्ध करती हों, लेकिन यह छँटाई विधियों को पारित वास्तविक संदर्भ को प्रभावित नहीं करती हैं। संख्या सरणी पंक्ति संख्या 1 में एक ही अनारक्षित प्रारंभिक प्रारूप में होगी।
नोट: क्लोन को छंटाई के तरीकों में किया जाना चाहिए।
Clone()
विधि लक्ष्य उदाहरण के संदर्भ देना नहीं है केवल आपके एक प्रति दे। CopyTo()
विधि प्रतियां एक मौजूदा उदाहरण में तत्वों।
दोनों ही लक्ष्य उदाहरण का संदर्भ नहीं देते हैं और जैसा कि कई सदस्य कहते हैं कि वे संदर्भ के बिना उथली प्रति (भ्रम की नकल) देते हैं यह महत्वपूर्ण है।
जवाब मुझे भ्रमित कर रहे हैं। जब आप उथली प्रति कहते हैं, तो इसका मतलब है कि वे अभी भी उसी पते की ओर इशारा कर रहे हैं। जिसका मतलब है, एक को बदलने के साथ-साथ दूसरे को भी बदलना होगा।
इसलिए यदि मेरे पास A = [1,2,3,4] है और मैं इसे क्लोन करता हूं और B = [1,2,3,4] प्राप्त करता हूं। अब, अगर मैं B [0] = 9. को बदलता हूं तो इसका मतलब है कि A अब A = [9,2,3,4] होगा। क्या वो सही है?
दोनों उथली प्रतियां हैं। CopyTo विधि एक गहरी प्रतिलिपि नहीं है। निम्नलिखित कोड की जाँच करें:
public class TestClass1
{
public string a = "test1";
}
public static void ArrayCopyClone()
{
TestClass1 tc1 = new TestClass1();
TestClass1 tc2 = new TestClass1();
TestClass1[] arrtest1 = { tc1, tc2 };
TestClass1[] arrtest2 = new TestClass1[arrtest1.Length];
TestClass1[] arrtest3 = new TestClass1[arrtest1.Length];
arrtest1.CopyTo(arrtest2, 0);
arrtest3 = arrtest1.Clone() as TestClass1[];
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
arrtest1[0].a = "new";
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
}
/* Output is
test1
test1
test1
new
new
new */
Clone()
इसका उपयोग केवल डेटा / सरणी की संरचना को कॉपी करने के लिए किया जाता है यह वास्तविक डेटा की प्रतिलिपि नहीं करता है।
CopyTo()
संरचना के साथ-साथ वास्तविक डेटा की प्रतिलिपि बनाता है।
कृपया ध्यान दें: स्ट्रिंग [] से स्ट्रिंगब्यूलर [] का उपयोग करने के बीच अंतर है।
स्ट्रिंग में - यदि आप स्ट्रिंग को बदलते हैं, तो हमने जो अन्य सरणियों की प्रतिलिपि बनाई है (CopyTo या क्लोन द्वारा) जो एक ही स्ट्रिंग की ओर इशारा करती है, वह नहीं बदलेगी, लेकिन मूल स्ट्रिंग सरणी एक नए स्ट्रिंग को इंगित करेगी, हालाँकि, अगर हम स्ट्रिंग स्ट्रिंग का उपयोग करते हैं एक सरणी में, स्ट्रिंग सूचक नहीं बदलेगा, इसलिए, यह इस सरणी के लिए हमारे द्वारा बनाई गई सभी प्रतियों को प्रभावित करेगा। उदाहरण के लिए:
public void test()
{
StringBuilder[] sArrOr = new StringBuilder[1];
sArrOr[0] = new StringBuilder();
sArrOr[0].Append("hello");
StringBuilder[] sArrClone = (StringBuilder[])sArrOr.Clone();
StringBuilder[] sArrCopyTo = new StringBuilder[1];
sArrOr.CopyTo(sArrCopyTo,0);
sArrOr[0].Append(" world");
Console.WriteLine(sArrOr[0] + " " + sArrClone[0] + " " + sArrCopyTo[0]);
//Outputs: hello world hello world hello world
//Same result in int[] as using String[]
int[] iArrOr = new int[2];
iArrOr[0] = 0;
iArrOr[1] = 1;
int[] iArrCopyTo = new int[2];
iArrOr.CopyTo(iArrCopyTo,0);
int[] iArrClone = (int[])iArrOr.Clone();
iArrOr[0]++;
Console.WriteLine(iArrOr[0] + " " + iArrClone[0] + " " + iArrCopyTo[0]);
// Output: 1 0 0
}
CopyTo
बनाम से संबंधित नहीं है Clone
। यह सिर्फ संदर्भ शब्दार्थ बनाम मूल्य शब्दार्थ है। int एक मूल्य प्रकार है, इसलिए आपको हर बार एक नई प्रतिलिपि मिलती है। StringBuilder में संदर्भ शब्दार्थ हैं, इसलिए आप उसी प्रति पर काम कर रहे हैं।