none
C# Arrays

Answers

  • Hi TonchiVZ,

    Thanks for the response.

    Still that didn't answer my question.

    Returning array from a method always makes copy of array which means that the compiler always returns the copy of array.

    Why is the copy always returned ??

    The compiler *doesn't* make a copy of the array when you return it.  If you do nothing manually, it will just return a reference to the same array.  In many cases this is a problem, if the method didn't create that array specifically for returning it.  If the array is a part of the internal state of the object it is likely important that the array not be modified, which means that you are responsible for making a copy yourself.

    So the point Eric is making is that you need to know that you ought to copy the array, in certain situations, before returning it.  The fact that it's non trivial to know when you need to make the copy, how to perform the copy (as evidenced by the discussion here about shallow/deep copies; you need to know how deep the copy needs to be), and you need to deal with the performance costs of those copies.

    Now not using arrays doesn't make all of those problems go away, but can make some go away, or make it more obvious to you as a programmer that they need to be addressed.

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:02 PM
    Monday, February 25, 2013 5:41 PM
  • Hi,

    No, IMHO he means that this is what YOU (not the compiler) have to do HERE (with "read only" data) as else if you return a real array that would store the actual metadata, the caller could then alter this data and then all other calls would start to return the wrong altered metadata. By returning a copy instead, the caller can alter the array at will and other calls will still return the good metadata (at the expense of making a copy each time you want to read back those metadata).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:02 PM
    Monday, February 25, 2013 5:55 PM
  • Hi,

    In this article http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx 

    its mentioned that Returning an array means that you have to make a fresh copy of the array every time you return it.

    I could not understand this why there would a fresh copy of array when it is returned from a method or property ??

    Can anyone explain this ??


    San

    The Quote in context:

    You probably should not return an array as the value of a public method or property, particularly when the information content of the array is logically immutable. Let me give you an example of where we got that horridly wrong in a very visible way in the framework.  If you take a look at the documentation for System.Type, you'll find that just looking at the method descriptions gives one a sense of existential dread. One sees a whole lot of sentences like "Returns an array of Type objects that represent the constraints on the current generic type parameter." Almost every method on System.Type returns an array it seems. 

    Now think about how that must be implemented. When you call, say, GetConstructors() on typeof(string), the implementation cannot possibly do this, as sensible as it seems.

    public class Type { 
       private ConstructorInfo[] ctorInfos;
       public ConstructorInfo[] GetConstructors()
       {
         if (ctorInfos == null) ctorInfos = GoGetConstructorInfosFromMetadata();
         return ctorInfos;
       }

    Why? Because now the caller can take that array and replace the contents of it with whatever they please. Returning an array means that you have to make a fresh copy of the array every time you return it

    He uses the term Logically immutable.  I take this to mean within the context that the CTOR metadata doesn't change.  His conclusion is that why send back a reference to an Array that allows someone else to change the data?  

    As Servy said, you have to know the context and when to do it. 


    JP Cowboy Coders Unite!

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:03 PM
    Monday, February 25, 2013 10:24 PM
  • @Returning array from a method always makes copy of array

    Plz notice this that  Returning an array means that you have to make a fresh copy of the array every time you return it.

    notice my bold, underlined part——You have to……This means you have to do that manually.

    Tuesday, February 26, 2013 1:38 AM

All replies

  • Array means a reference type, so if you don't make a fresh copy, it will refer the original source and when it is changed, the value of array itself will be changed, too.

    So you have to do a deep copy, Something like using:

    Array.Copy

    http://msdn.microsoft.com/en-US/library/system.array.copy.aspx


    帮助一起改进论坛质量?提交你的意见于此。
    我的博客园
    慈善点击,点击此处
    和谐拯救危机,全集下载,净化人心

    • Proposed as answer by Tonchi91 Saturday, February 23, 2013 1:57 AM
    Saturday, February 23, 2013 1:55 AM
  • Well I cant swear to it, but it sounds to me like they're trying to say that an Array cant be passed as reference? Dont really use arrays much anymore.

    For objects that can be referenced all that is passed to or returned from a method (under the hood) is a pointer to the original object.

    Saturday, February 23, 2013 1:57 AM
  • Hello,

    Array.Copy does not do a deep copy if the array contains reference types, in this case it will create a shallow copy to the references that points to the objects.


    Regards,

    Eyal Shilony

    Saturday, February 23, 2013 2:01 AM
    Moderator
  • Hello,

    Array.Copy does not do a deep copy if the array contains reference types, in this case it will create a shallow copy to the references that points to the objects.


    Regards,

    Eyal Shilony

    Thx!!!!!!!!!

    My addition:

    If ur array contains something about Struct type, plz use Array.Copy;)

    But if it still contains reference type, plz use Serialization and Deserialization. And if your array contains a self-made class, plz mark it with the attribute "[Serializable]".

    Sample:

    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
     
    namespace CSharp
    {
        [Serializable]
        class Student
        {
            public int Id { getset; }
            public string Name { getset; }
            public override string ToString()
            {
                return Id + ":" + Name;
            }
        }
     
        class Program
        {
            static void Main(string[] args)
            {
                Student[] students = {new Student{Id=1,Name="aa"},new Student{Id=2,Name="bb"} };
                BinaryFormatter bf = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                //Serialization!
                bf.Serialize(msstudents);
                //Deserialization!
                ms.Position = 0;
                Student[] students2 = (Student[])bf.Deserialize(ms);
                //Test
                students[0= new Student { Id = 3Name = "ccc" };
                Console.WriteLine(students[0]);
                Console.WriteLine(students2[0]);
            }
     
        }
    }

    帮助一起改进论坛质量?提交你的意见于此。
    我的博客园
    慈善点击,点击此处
    和谐拯救危机,全集下载,净化人心 

    Saturday, February 23, 2013 2:45 AM
  • Hi TonchiVZ,

    Thanks for the response.

    Still that didn't answer my question.

    Returning array from a method always makes copy of array which means that the compiler always returns the copy of array.

    Why is the copy always returned ??


    San

    Monday, February 25, 2013 4:46 PM
  • Hi TonchiVZ,

    Thanks for the response.

    Still that didn't answer my question.

    Returning array from a method always makes copy of array which means that the compiler always returns the copy of array.

    Why is the copy always returned ??

    The compiler *doesn't* make a copy of the array when you return it.  If you do nothing manually, it will just return a reference to the same array.  In many cases this is a problem, if the method didn't create that array specifically for returning it.  If the array is a part of the internal state of the object it is likely important that the array not be modified, which means that you are responsible for making a copy yourself.

    So the point Eric is making is that you need to know that you ought to copy the array, in certain situations, before returning it.  The fact that it's non trivial to know when you need to make the copy, how to perform the copy (as evidenced by the discussion here about shallow/deep copies; you need to know how deep the copy needs to be), and you need to deal with the performance costs of those copies.

    Now not using arrays doesn't make all of those problems go away, but can make some go away, or make it more obvious to you as a programmer that they need to be addressed.

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:02 PM
    Monday, February 25, 2013 5:41 PM
  • Hi,

    No, IMHO he means that this is what YOU (not the compiler) have to do HERE (with "read only" data) as else if you return a real array that would store the actual metadata, the caller could then alter this data and then all other calls would start to return the wrong altered metadata. By returning a copy instead, the caller can alter the array at will and other calls will still return the good metadata (at the expense of making a copy each time you want to read back those metadata).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:02 PM
    Monday, February 25, 2013 5:55 PM
  • Hi,

    In this article http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx 

    its mentioned that Returning an array means that you have to make a fresh copy of the array every time you return it.

    I could not understand this why there would a fresh copy of array when it is returned from a method or property ??

    Can anyone explain this ??


    San

    The Quote in context:

    You probably should not return an array as the value of a public method or property, particularly when the information content of the array is logically immutable. Let me give you an example of where we got that horridly wrong in a very visible way in the framework.  If you take a look at the documentation for System.Type, you'll find that just looking at the method descriptions gives one a sense of existential dread. One sees a whole lot of sentences like "Returns an array of Type objects that represent the constraints on the current generic type parameter." Almost every method on System.Type returns an array it seems. 

    Now think about how that must be implemented. When you call, say, GetConstructors() on typeof(string), the implementation cannot possibly do this, as sensible as it seems.

    public class Type { 
       private ConstructorInfo[] ctorInfos;
       public ConstructorInfo[] GetConstructors()
       {
         if (ctorInfos == null) ctorInfos = GoGetConstructorInfosFromMetadata();
         return ctorInfos;
       }

    Why? Because now the caller can take that array and replace the contents of it with whatever they please. Returning an array means that you have to make a fresh copy of the array every time you return it

    He uses the term Logically immutable.  I take this to mean within the context that the CTOR metadata doesn't change.  His conclusion is that why send back a reference to an Array that allows someone else to change the data?  

    As Servy said, you have to know the context and when to do it. 


    JP Cowboy Coders Unite!

    • Marked as answer by Sanjay Sutar Tuesday, February 26, 2013 4:03 PM
    Monday, February 25, 2013 10:24 PM
  • @Returning array from a method always makes copy of array

    Plz notice this that  Returning an array means that you have to make a fresh copy of the array every time you return it.

    notice my bold, underlined part——You have to……This means you have to do that manually.

    Tuesday, February 26, 2013 1:38 AM
  • Thanks servy42 and others for the response. Now I am pretty clear.

    San

    Tuesday, February 26, 2013 4:08 PM