System.Array.CopyTo() Issue - c#

I have researched this issue and cannot seem to find the any worthwhile answer. What is the difference between System.Array.CopyTo() and System.Array.Clone()?

System.Array.CopyTo will copy to existing array of the similar size(If size of destination is less than size of source data, exception will be thrown). System.Array.Clone will create a new array.
From MSDN:
Array.CopyTo : Copies all the elements of the current one-dimensional Array to the specified one-dimensional Array starting at the specified destination Array index. The index is specified as a 32-bit integer.
Array.Clone: Creates a shallow copy of the Array.

The CopyTo method will allow you to append to another array.
for example, if you have an array of size 100 and another array of size 200, you can use the CopyTo method to Copy the array of size 100 to the last one hundred slots of the larger array. Or even copy it to the larger array starting at position 50 etc.
Clone will simply create an identical (shallow copy) of your existing array.

Related

Add float[] array to a list<float[]> and clear contents of array without losing the list contents

In C#, how can I copy contents of a float[] array () to a list<float[]> such that when I clear the float[] array, the contents of the list<float[]> is not touched (i.e. a copy)?
Some script is provided in the attached picture where:
there are 21 points whose values increase by 0.5 starting at 0 and ending in 10.
The ceiling of this point value, gives a suffix for 32 bit binary file for instance when the point value is 0.5 or 1, binary file "File1.bin" will be used in the calculations while for point value 1.5 and 2, binary file "File2.bin" will be used and so forth.
Each file is a 32 bit float-point binary with a fixed number of elements when read as 32 bit binary values.
I want to go over all the points (in a for loop), and if I have not read a binary file for that point, read the contents of the file and save it in a list. Since the file is read into a float[] array ("oneFile" variable in the script), my incremental list is List<float[]> (variable "allFiles" in the script).
At the end of each iteration in the for loop, I'd like to clear the contents of the array "oneFile" and read into it potentially in the future iteration. However, this obviously also clears the contents of "allFiles". How can I avoid this?
enter image description here
Instead of clearing the array with Array.Clear, which just sets a range of elements in an array to the default value of each element type, you should set oneFile to a new instance of an array, so it's no longer referring to the same instance we just added to allFiles.
In other words,
replace: Array.Clear(oneFile, 0, oneFile.Length);
(this just assignes all the items to 0)
with: oneFile = new float[FileSizeBytes / 4];
(this changes the reference to a new array populated with items initialized to 0)

"I i can traverse a list using indexing as i do in an array.Why can't i add an item in a list as i do in an array using indexing."

Why do I need to use the Add() to add elements to a List. Why can't I use indexing and do it. When I traverse the elements through the List I do it using the help of indexes.
int head = -1;
List<char> arr = new List<char>();
public void push(char s)
{
++head;
arr[head] = s;//throws runtime error.
arr.Add(s);
}
It doesn't throw any error during compile time. But throws an error at runtime stating IndexOutOfRangeException.
++head;
arr[head] = s;
This attempts to set element 1 of the list to s, but there is no element 1 yet because you've not added anything, or set the length of the list.
When you create an array, you define a length, so each item has a memory address that can be assigned to.
Lists are useful when you don't know how many items you're going to have, or what their index is going to be.
Arrays are fixed sizes. Once you allocate them, you can not add or remove "slots" from it. So if you need it to be bigger, you need to:
Detect that you need a bigger array.
Allocate a new, bigger array
copy all existing values to teh new, bigger array
start using the bigger array from now on everywhere
All that Lists do is automate that precise process. It will automatically detect that it needs to increase during Add() and then do step 2-4 automagically. It is even responsible to pick the initial size and by how much to grow it (to avoid having to grow to often.
They could in theory jsut react to List[11000] by growing the size to 11000. But chances are very big, that this value is a huge mistake. And preventing the Progarmmer from doing huge mistakes is what half the classes and compiler rules (like strong typisation) are there for. So they force you to use Add() so such a mistake can not happen.
Actually calling myArray[2] does not add the element, but just assigns the object to the specified index within the array. If the array´s size is less you´d get an IndexOutOfBoundsException, as in a list<T> also. So also in case of an array using the indexer assumes you actually have that many elements:
var array = new int[3];
array[5] = 4; // bang
This is because arrays have a fixed size which you can´t change. If you assign an object to an index greater the arrays size you get the exat same exception as for a List<T> also, there´s no difference here.
The only real difference here is that when using new array[3] you have an array of size 3 with indices up to 2 and you can call array[2]. However this would just return the default-value - in case of int this is zero. When using new List<int>(3) in contrast you don´t have actually three elements. In fact the list has no items at all and calling list[2] throws the exception. The parameter to a list is just the capacity, which is a parameter for the runtime to indicate when the underlying array of a list should be resized - an ability your array does not even have.
A list is an array wrapper, where the internal array size is managed by its methods. The constructor that takes a capacity simply creates an array of that size internally, but the count property (which reflects the count elements that has been added) will be zero. So in essence, zero slots in the array has been assigned a value.
The size of an array is managed by you the programmer. That is why you have to call static methods like System.Array.Resize (notice that the array argument is ref), if you want to change an array yourself. That method allocates a new chunk of memory for the new size.
So to sum up, the list essentially manages an array for you, and as such, the tradeoff is that you can only access as many array-like slots as has been added to it.

C# byte array - writing in the middle

I have the task of reading data from a source in chunks, and storing the entire result in a byte array. Specifically, I need to make subsequent calls to "Socket.Receive". I would like to allocate the byte array with the final size in advance, and each time give the position within the array to copy data into. This, to avoid an extra copy.
In C++, you simply give the offset of the array. Could not figure out how to give the Receive method a location in the middle of the byte array...
Can this be done in C#?
There are overloads to Receive that accept the offset and count to read. You can use them: https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receive(v=vs.110).aspx - for a specific example: https://msdn.microsoft.com/en-us/library/w3xtz6a5(v=vs.110).aspx

Filling one byte[] with multiple byte[]s

I created an application that stores byte arrays in my SQLiteDatabase.
This same application also selects the byte arrays from the database every 'x' seconds.
The dataflow of my application is as follow:
Application - > SQLiteDatabase -> Application
My question is:
How do I fill one byte array with all the incoming byte arrays from the SQLiteDatabase?
For example:
Byte[] Data;
Needs to be filled with the following byte array:
Byte[] IncomingData;
IncomingData is constantly being filled by the SQLiteDatabase.
Data needs to be filled with IncomingData constantly.
Can someone help me out?
Just use Concat:
data1.Concat(IncomingData);
You'll need to add the System.Linq namespace reference.
There are a few approaches you can take.
Use a List<byte> and List.AddRange
Use LINQ's Enumerable.Concat
Use Array.Copy and do it all manually
Of the three, if possible go with the List as it will (likely) reduce the amount of array copying required. This is what List's are made for, they use an array behind the scenes with a certain capacity, it starts at 4 and doubles when it hits the capacity. The capacity can even be set to some large number with the list.Capacity property or the constructor that takes an int much like you can with an array. You can always bring the list back using List.ToArray.
Enumerable.Concat will likely only create an array of the minimum size, meaning a new array needs to be created every time you get some more bytes.

Why does list insertion fail when sufficient size is provided on construction?

If we have the following variable declaration:
List<int> list = new List(5);
Why does this:
list.insert(2, 3);
fail with the following error:
Index must be within the bounds of the List.
What's the point of providing the initial size?
All the initial size does is provide a hint to the implementation to have at least a given capacity. It does not create a list filled with N default entries; emphasis mine:
Initializes a new instance of the List<T> class that is empty and has the specified initial capacity.
If you continue through the MSDN entry to the Remarks section, you'll find why this constructor overload is provided (again, emphasis mine):
The capacity of a List<T> is the number of elements that the List<T> can hold. As elements are added to a List<T>, the capacity is automatically increased as required by reallocating the internal array.
If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the List<T>.
In short List<T>.Count is not the same as List<T>.Capacity ("If Count exceeds Capacity while adding elements, the capacity is increased...").
You receive the exception because the list only logically contains the items you add, changing the capacity does not change the number of items logically stored. If you were to set List<T>.Capacity to less than List<T>.Count we can test this behavior going the other direction:
Unhandled Exception: System.ArgumentOutOfRangeException: capacity was less than
the current size.
Parameter name: value
at System.Collections.Generic.List`1.set_Capacity(Int32 value)
To perhaps create the behavior you're looking for:
public static List<T> CreateDefaultList<T>(int entries)
{
return new List<T>(new T[entries]);
}
Internally a List(T) is implemented using an array in the background. When you initialize the list that way you are just setting the size of the underlying array which resizes as the list grows. Thus, you are initializing the initial capacity. It doesn't mean that your list has that many elements.
You add elements to the list by first initializing it and then add elements to it with .Add(item).
Because insert assumes that the list actually has that many items already inserted- capacity is not the same thing as size. Initializing the list with a given capacity just sets the size of the internal array- it is an optimization to prevent array resizes when you know the number of items that you are going to be inserting.
The List(int) constructor specifies initial capacity of the list. It does not specify the number of initial elements. Upon construction a list is empty so, any insertion can only be done at index 0.
The size in the constructor tells it how much to allocate for the background array - it is still, however, empty (just: empty with a certain amount of initial space).
You can ony insert into the used part of the list, or at the end.
The initial size is used to indicate the size of the internal array, initially.
When you insert items into a List, it stores them in an array. When the array is full, it creates a new array of double the size, and copies all of the items. If you have an idea that you are going to be putting in 5000 items, you would want to specify that hint so it doesn't end up doing a lot of array resizing / copying.
The initial size does not indicate that there are any items in the list though.
That is because the integer you specify in the constructor is the amount that the List can hold. When items are added, the list is automatically increased. The resizing is avoided when you specify an initial capacity that matches the number of items that you want to add.
However, you still have to use the Add method to add new items.
See the remarks section in the documentation
Use
listItem.Addrange(number);

Categories

Resources