Deep thoughts on .ToArray()

  • Thread starter Thread starter RayLopez99
  • Start date Start date
R

RayLopez99

Now that I've learned about 90% of whatever there is to learn about C#
in about six months time, I'm going back and looking at some old
programs I wrote my first month, and seeing where I can improve
efficiency.

One (bad? that's the question) habit I picked up the first month of
coding in C# is found below. My question: is this really a bad habit
or a safe "belt and suspenders" approach?

// here it is:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2]{1,2};

int Length1 = ASecondArrayOfInts.Length; //needed?

AnIntegerArray = new int[Length1]; //needed?

AnIntegerArray = ASecondArrayOfInts.ToArray();

// can the above few lines - "needed?" - be eliminated (deleted) as
they are already included in:

AnIntegerArray = ASecondArrayOfInts.ToArray(); //?

// I am looking to make a shallow copy of the ASecondArrayOfInts,
which I think is automatically done with .ToArray() (which uses
implicitly 'new'), right?

RL
 
RayLopez99 said:
Now that I've learned about 90% of whatever there is to learn about C#
in about six months time, I'm going back and looking at some old
programs I wrote my first month, and seeing where I can improve
efficiency.

One (bad? that's the question) habit I picked up the first month of
coding in C# is found below. My question: is this really a bad habit
or a safe "belt and suspenders" approach?

// here it is:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2]{1,2};

int Length1 = ASecondArrayOfInts.Length; //needed?

AnIntegerArray = new int[Length1]; //needed?

AnIntegerArray = ASecondArrayOfInts.ToArray();

// can the above few lines - "needed?" - be eliminated (deleted) as
they are already included in:

AnIntegerArray = ASecondArrayOfInts.ToArray(); //?

// I am looking to make a shallow copy of the ASecondArrayOfInts,
which I think is automatically done with .ToArray() (which uses
implicitly 'new'), right?

The most basic question is: what happened when you tested this code?

Clearly the answer is "I didn't test it," because if you had you would have
discovered that arrays do not have a ToArray() method; that's the ArrayList.

Arrays have a CopyTo() method, and they require an already-dimensioned array
as an argument, so they don't allow you to allocate a new array on the fly.
Your shallow copy would be quickest like this (assuming you want to declare
the first array and set it later):

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[] { 1, 2 }; // You don't need to specify
a size when initializing

AnIntegerArray = new int[ASecondArrayOfInts.Length];

ASecondArrayOfInts.CopyTo(AnIntegerArray, 0);
 
Hello!

You can even skip the new int[] and just write
int[] myInt = {1,2};
insted of
int[] ASecondArrayOfInts = new int[] { 1, 2 }; // You don't need to specify
a size when initializing


//Tony

Jeff Johnson said:
RayLopez99 said:
Now that I've learned about 90% of whatever there is to learn about C#
in about six months time, I'm going back and looking at some old
programs I wrote my first month, and seeing where I can improve
efficiency.

One (bad? that's the question) habit I picked up the first month of
coding in C# is found below. My question: is this really a bad habit
or a safe "belt and suspenders" approach?

// here it is:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2]{1,2};

int Length1 = ASecondArrayOfInts.Length; //needed?

AnIntegerArray = new int[Length1]; //needed?

AnIntegerArray = ASecondArrayOfInts.ToArray();

// can the above few lines - "needed?" - be eliminated (deleted) as
they are already included in:

AnIntegerArray = ASecondArrayOfInts.ToArray(); //?

// I am looking to make a shallow copy of the ASecondArrayOfInts,
which I think is automatically done with .ToArray() (which uses
implicitly 'new'), right?

The most basic question is: what happened when you tested this code?

Clearly the answer is "I didn't test it," because if you had you would
have discovered that arrays do not have a ToArray() method; that's the
ArrayList.

Arrays have a CopyTo() method, and they require an already-dimensioned
array as an argument, so they don't allow you to allocate a new array on
the fly. Your shallow copy would be quickest like this (assuming you want
to declare the first array and set it later):

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[] { 1, 2 }; // You don't need to
specify a size when initializing

AnIntegerArray = new int[ASecondArrayOfInts.Length];

ASecondArrayOfInts.CopyTo(AnIntegerArray, 0);
 
But just to be clear the compiler simply infers the missing sytax for you,
none of those 3 options are more or less efficient than the other -- all the
same once compiled.


Jeff Johnson said:
You can even skip the new int[] and just write
int[] myInt = {1,2};
insted of
int[] ASecondArrayOfInts = new int[] { 1, 2 }; // You don't need to
specify a size when initializing

In .NET 2.0 or later, yes.
 
Jeff Johnson said:
RayLopez99 said:
Now that I've learned about 90% of whatever there is to learn about C#
in about six months time, I'm going back and looking at some old
programs I wrote my first month, and seeing where I can improve
efficiency.

One (bad? that's the question) habit I picked up the first month of
coding in C# is found below. My question: is this really a bad habit
or a safe "belt and suspenders" approach?

// here it is:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2]{1,2};

int Length1 = ASecondArrayOfInts.Length; //needed?

AnIntegerArray = new int[Length1]; //needed?

AnIntegerArray = ASecondArrayOfInts.ToArray();

// can the above few lines - "needed?" - be eliminated (deleted) as
they are already included in:

AnIntegerArray = ASecondArrayOfInts.ToArray(); //?

// I am looking to make a shallow copy of the ASecondArrayOfInts,
which I think is automatically done with .ToArray() (which uses
implicitly 'new'), right?

The most basic question is: what happened when you tested this code?

Clearly the answer is "I didn't test it," because if you had you would
have discovered that arrays do not have a ToArray() method; that's the
ArrayList.

Arrays have a CopyTo() method, and they require an already-dimensioned
array as an argument, so they don't allow you to allocate a new array on
the fly. Your shallow copy would be quickest like this (assuming you want
to declare the first array and set it later):

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[] { 1, 2 }; // You don't need to
specify a size when initializing

AnIntegerArray = new int[ASecondArrayOfInts.Length];

ASecondArrayOfInts.CopyTo(AnIntegerArray, 0);


The .ToArray() method works fine for me.
 
The .ToArray() method works fine for me.

What version of the Framework? In 2.0, ToArray() does not appear in
Intellisense and when compiling I get

'System.Array' does not contain a definition for 'ToArray'
 
What version of the Framework? In 2.0, ToArray() does not appear in
Intellisense and when compiling I get

    'System.Array' does not contain a definition for 'ToArray'

Sorry, I meant List, not Array, which FTM I think implicitly
understood. But your example was good, and it's been noted.

In any event I've cut out the "unnecessary" (implied) steps now...and
the code seems to work fine, as before.

RL
 
Jeff Johnson said:
What version of the Framework? In 2.0, ToArray() does not appear in
Intellisense and when compiling I get

'System.Array' does not contain a definition for 'ToArray'

I'm using 3.5 within VS 2008. Intellisense comes up fine.
 
I'm using 3.5 within VS 2008. Intellisense comes up fine.

Not here. I just put this in a class in VS 2008:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2] { 1, 2 };

AnIntegerArray = ASecondArrayOfInts.ToArray();

and tried to compile. I got this:

'System.Array' does not contain a definition for 'ToArray' and no extension
method 'ToArray' accepting a first argument of type 'System.Array' could be
found (are you missing a using directive or an assembly reference?)

I even changed the target Framework to 3.5 and still got the same error.
 
Sorry, I meant List, not Array, which FTM I think implicitly
understood. But your example was good, and it's been noted.

....huh? Did you mean "ArrayList" or an actual, generic List<T>? Either way,
your sample code used plain old arrays.
 
Jeff Johnson said:
I'm using 3.5 within VS 2008. Intellisense comes up fine.

Not here. I just put this in a class in VS 2008:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2] { 1, 2 };

AnIntegerArray = ASecondArrayOfInts.ToArray();

and tried to compile. I got this:

'System.Array' does not contain a definition for 'ToArray' and no
extension method 'ToArray' accepting a first argument of type
'System.Array' could be found (are you missing a using directive or an
assembly reference?)

I even changed the target Framework to 3.5 and still got the same error.


Interesting! I found the secret is "using System.Linq". If I remove it, I
get the same error as you. I bet you don't have it as you moved from
2.0 --> 3.5, right?
 
RayLopez99 said:
Now that I've learned about 90% of whatever there is to learn about C#
in about six months time,

Give it another six months, and you will realise that then you have
really learned about 50%. ;)
I'm going back and looking at some old
programs I wrote my first month, and seeing where I can improve
efficiency.

One (bad? that's the question) habit I picked up the first month of
coding in C# is found below. My question: is this really a bad habit
or a safe "belt and suspenders" approach?

// here it is:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2]{1,2};

int Length1 = ASecondArrayOfInts.Length; //needed?

No, it's not needed. You don't need to store the value of the property
in a variable to use it.
AnIntegerArray = new int[Length1]; //needed?

Definitely not. You are creating an array that is just thrown away when
the reference is replaced with another array in the next line.
AnIntegerArray = ASecondArrayOfInts.ToArray();

// can the above few lines - "needed?" - be eliminated (deleted) as
they are already included in:

AnIntegerArray = ASecondArrayOfInts.ToArray(); //?

// I am looking to make a shallow copy of the ASecondArrayOfInts,
which I think is automatically done with .ToArray() (which uses
implicitly 'new'), right?

Using ToArray on an array is only possible when targeting framework 3.5
where the IEnumerable interface (which the Array class implements) has
that extension method.

The ToArray method creates a Buffer object from the IEnumerable (the
array in this case). This normally means that the items in the
collections are enumerated and added to an internal array one at a time,
expanding the target array when needed. Then the buffer would create yet
another array and copy the items to it and return as result. However, in
the special case when the IEnumerable object also implements ICollection
(which the Array class does), it can use the CopyTo method to copy the
data to the new array without having to enumerate all the items. So, the
items will only be copied once in this case.

Still, there is a bit of overhead when calling the ToArray method
compared with calling the Array.CopyTo method yourself. Also, it's not
so obvious that the ToArray method actually creates a shallow copy. For
an array the ToArray method could just have returned the array object
itself, just as the ToString method of the String class just returns the
string object itself.
 
Jeff said:
What version of the Framework? In 2.0, ToArray() does not appear in
Intellisense and when compiling I get

'System.Array' does not contain a definition for 'ToArray'

In framework 3.5. The ToArray method is an extension to the
IEnumerable<T> interface.
 
I'm using 3.5 within VS 2008. Intellisense comes up fine.

Not here. I just put this in a class in VS 2008:

int[] AnIntegerArray;

int[] ASecondArrayOfInts = new int[2] { 1, 2 };

AnIntegerArray = ASecondArrayOfInts.ToArray();

and tried to compile. I got this:

'System.Array' does not contain a definition for 'ToArray' and no
extension method 'ToArray' accepting a first argument of type
'System.Array' could be found (are you missing a using directive or an
assembly reference?)

I even changed the target Framework to 3.5 and still got the same error.


Interesting! I found the secret is "using System.Linq". If I remove it,
I get the same error as you. I bet you don't have it as you moved from
2.0 --> 3.5, right?

Bingo!
 
Give it another six months, and you will realise that then you have
really learned about 50%. ;)

You said that six months ago Goran! But I feel like a guru. ;-)
Using ToArray on an array is only possible when targeting framework 3.5
where the IEnumerable interface (which the Array class implements) has
that extension method.

Yes, I have that framework.
The ToArray method creates a Buffer object from the IEnumerable (the
array in this case). This normally means that the items in the
collections are enumerated and added to an internal array one at a time,
expanding the target array when needed. Then the buffer would create yet
another array and copy the items to it and return as result. However, in
the special case when the IEnumerable object also implements ICollection
(which the Array class does), it can use the CopyTo method to copy the
data to the new array without having to enumerate all the items. So, the
items will only be copied once in this case.

Still, there is a bit of overhead when calling the ToArray method
compared with calling the Array.CopyTo method yourself.

OK, I might keep that in mind and use .CopyTo in the future

Also, it's not
so obvious that the ToArray method actually creates a shallow copy. For
an array the ToArray method could just have returned the array object
itself, just as the ToString method of the String class just returns the
string object itself.

OK, I understand you mean "obvious" as in somebody else reading your
code, who is not experienced in C#.

Thanks for your help.

RL
 
RayLopez99 said:
You said that six months ago Goran! But I feel like a guru. ;-)

Yes, you may have done great progress, but judging from your questions
here lately I don't think that you have learned 90% of C#. I don't even
consider myself to know as much as 90% of C#, and I already know the
answers to almost all of your questions...
OK, I understand you mean "obvious" as in somebody else reading your
code, who is not experienced in C#.

That doesn't have so much to do with experience, but rather the specific
knowledge what this ToArray method does.
 
Göran Andersson said:
Yes, you may have done great progress, but judging from your questions
here lately I don't think that you have learned 90% of C#. I don't even
consider myself to know as much as 90% of C#, and I already know the
answers to almost all of your questions...

Funny thing knowledge, the more you have the more you are aware that you
still need to learn. Hence when you have a little you feel you only have a
little more to learn. However once you've learnt a little more the more you
realise you still have to learn. So quantifying knowledge has a strange
curve starting at 0% passing throught 90% and then falling to settle at
about 50% (after many years in a narrow field that may climb again).

This is the reason why Teenagers (read also earlier twenties) think they
know everything and are invincible.
 
Funny thing knowledge,  the more you have the more you are aware that you
still need to learn.  Hence when you have a little you feel you only have a
little more to learn. However once you've learnt a little more the more you
realise you still have to learn.  So quantifying knowledge has a strange
curve starting at 0% passing throught 90% and then falling to settle at
about 50% (after many years in a narrow field that may climb again).

This is the reason why Teenagers (read also earlier twenties) think they
know everything and are invincible.

Philosophically, this has been noted before, by none other than the
famous Greek philosopher Socrates. He said: "I know one thing, that I
know nothing". His rationale: the Oracle at Delphi (a famous group
of prophets, at the mountain Delphi in northern Athens region) said
that Socrates was the smartest man in the world. Since Socrates
thought himself ordinary, he knew the prophet was right, but could not
fanthom why. He spent the rest of his life figuring out why, and
concluded that (due to his infamous "Socratic Method" of question and
answer, still used in university today) it was because Socrates knew
he didn't know anything, while the rest of humanity thought they knew
everything. Socrates knew of the known unknowns and unknown unknowns,
to borrow a phrase popularized by Donald Rumsfield. Political
statement: if President Bush had this knowledge, not to mention
Donald Rumsfield, the USA would be better off today IMO.

RL
 
if President Bush had this knowledge, not to mention
Donald Rumsfield, the USA would be better off today IMO.

RL

That was *very* deep thoughts on .ToArray()

- Michael Starberg
 
Back
Top