23

How can I copy a string[] from another string[]?

Suppose I have string[] args. How can I copy it to another array string[] args1?

shekhar
  • 1,372
  • 2
  • 16
  • 23
Arunachalam
  • 5,417
  • 20
  • 52
  • 80

3 Answers3

34
  • To create a completely new array with the same contents (as a shallow copy): call Array.Clone and just cast the result.
  • To copy a portion of a string array into another string array: call Array.Copy or Array.CopyTo

For example:

using System;

class Test
{
    static void Main(string[] args)
    {
        // Clone the whole array
        string[] args2 = (string[]) args.Clone();

        // Copy the five elements with indexes 2-6
        // from args into args3, stating from
        // index 2 of args3.
        string[] args3 = new string[5];
        Array.Copy(args, 2, args3, 0, 5);

        // Copy whole of args into args4, starting from
        // index 2 (of args4)
        string[] args4 = new string[args.Length+2];
        args.CopyTo(args4, 2);
    }
}

Assuming we start off with args = { "a", "b", "c", "d", "e", "f", "g", "h" } the results are:

args2 = { "a", "b", "c", "d", "e", "f", "g", "h" }
args3 = { "c", "d", "e", "f", "g" }
args4 = { null, null, "a", "b", "c", "d", "e", "f", "g", "h" } 
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hi Jon, why is string array clone a 'deep' clone? I mean I know Array.Clone() is a shallow copy; while it does do a shallow copy on other reference types (e.g. CultureInfo) it somehow does a 'deep' copy on string array. For example, if I clone an array containing "Hello", "World"; after the clone, I set the first element to null. Then I expect the 1st element of the cloned array should also be null but it's still Hello. Hope you know what I mean without being able to show the code sample in the comment. – dragonfly02 Jan 27 '15 at 10:57
  • @stt106: Why would you expect it to be null? It's creating a shallow copy, i.e. creating a new array of the same size, and copying each value from the original array to the new array. You'd see exactly the same behaviour with `CultureInfo`. – Jon Skeet Jan 27 '15 at 11:00
  • But the references in the new Array point to the **same** objects that the references in the original Array point to; hence if either the original or cloned (new) array is modified then the other array should **reflect the modification** as well? – dragonfly02 Jan 27 '15 at 11:35
  • @stt106: No, because modifying the *array* isn't the same as modifying the object that a reference refers to. If you write `array[0] = null` that's saying "Ignore the old value in the array; the new value is null". Why would that affect the other array? Imagine I have a printed page with a list of URLs on, and I photocopy that and give you the photocopy. If I scribble out one of the URLs, that doesn't affect your copy *at all*. If on the other hand I modify the page that one of the URLs refers to, you *will* see the difference. – Jon Skeet Jan 27 '15 at 11:41
  • 1
    Ah got you. Thanks for the example in your explanation. I guess string isn't the best reference type example to test array shallow copy due to its **immutability**... probably that's why MSDN uses an example of CultureInfo rather than string – dragonfly02 Jan 27 '15 at 11:58
28

Allocate space for the target array, that use Array.CopyTo():

targetArray = new string[sourceArray.Length];
sourceArray.CopyTo( targetArray, 0 );
sharptooth
  • 167,383
  • 100
  • 513
  • 979
0

The above answers show a shallow clone; so I thought I add a deep clone example using serialization; of course a deep clone can also be done by looping through the original array and copy each element into a brand new array.

 private static T[] ArrayDeepCopy<T>(T[] source)
        {
            using (var ms = new MemoryStream())
            {
                var bf = new BinaryFormatter{Context = new StreamingContext(StreamingContextStates.Clone)};
                bf.Serialize(ms, source);
                ms.Position = 0;
                return (T[]) bf.Deserialize(ms);
            }
        }

Testing the deep clone:

 private static void ArrayDeepCloneTest()
        {
            //a testing array
            CultureInfo[] secTestArray = { new CultureInfo("en-US", false), new CultureInfo("fr-FR") };

            //deep clone
            var secCloneArray = ArrayDeepCopy(secTestArray);

            //print out the cloned array
            Array.ForEach(secCloneArray, x => Console.WriteLine(x.DateTimeFormat.DateSeparator));

            //modify the original array
            secTestArray[0].DateTimeFormat.DateSeparator = "-";

            Console.WriteLine();
            //show the (deep) cloned array unchanged whereas a shallow clone would reflect the change...
            Array.ForEach(secCloneArray, x => Console.WriteLine(x.DateTimeFormat.DateSeparator));
        }
dragonfly02
  • 3,403
  • 32
  • 55