Good day all
So I know that this is a fairly widely discussed issue, but I can\'t seem to find a definitive answer. I know that you can do what I am asking for using a L
I surggest using the CopyTo method, so here is my two cent on a solution that is easy to explain and simple. The CopyTo method copies the array to another array at a given index. In this case myArray is copied to newArr starting at index 1 so index 0 in newArr can hold the new value.
"Push" to array online demo
var newValue = 1;
var myArray = new int[5] { 2, 3, 4, 5, 6 };
var newArr = new int[myArray.Length + 1];
myArray.CopyTo(newArr, 1);
newArr[0] = newValue;
//debug
for(var i = 0; i < newArr.Length; i++){
Console.WriteLine(newArr[i].ToString());
}
//output
1
2
3
4
5
6
Check out this documentation page: https://msdn.microsoft.com/en-us/library/ms132397(v=vs.110).aspx
The Add function is the first one under Methods.
C# is a little different in this respect with JavaScript. Because of the strict checks, you define the size of the array and you are supposed to know everything about the array such as its bounds, where the last item was put and what items are unused. You are supposed to copy all the elements of the array into a new, bigger one, if you want to resize it.
So, if you use a raw array, there's no other way other than to maintain the last empty, available index
assign items to the array at this index, like you're already doing.
However, if you'd like to have the runtime maintain this information and completely abstract away the array, but still use an array underneath, then C# provides a class named ArrayList
that provides this abstraction.
The ArrayList
abstracts a loosely typed array of Object
s. See the source here.
It takes care of all the issues like resizing the array, maintaining the last index that is available, etc. However, it abstracts / encapsulates this information from you. All you use is the ArrayList
.
To push an item of any type into the underlying array at the end of the underlying array, call the Add method on the ArrayList
like so:
/* you may or may not define a size using a constructor overload */
var arrayList = new ArrayList();
arrayList.Add("Foo");
EDIT: A note about type restriction
Like every programming language and runtime does, C# categorizes heap objects from those that will not go on the heap and will only stay on the function's argument stack. C# notes this distinction by the name Value types vs. Reference types. All things whose value goes on the stack are called Value types, and those that will go on the heap are called Reference types. This is loosely similar to JavaScript's distinction between objects and literals.
You can put anything into an ArrayList
in C#, whether the thing is a value type or a reference type. This makes it closest to the JavaScript array in terms of typelessness, although neither of the three -- the JavaScript array, the JavaScript language and the C# ArrayList -- are actually type-less.
So, you could put a number literal, a string literal, an object of a class you made up, a boolean, a float, a double, a struct, just about anything you wanted into an ArrayList
.
That is because the ArrayList
internally maintains and stores all that you put into it, into an array of Object
s, as you will have noted in my original answer and the linked source code.
And when you put something that isn't an object, C# creates a new object of type Object
, stores the value of the thing you put into the ArrayList
into this new Object
type object. This process is called boxing and isn't very much unlike the JavaScript boxing mechanism.
For e.g. in JavaScript, while you could use a numeric literal to invoke a function on the Number
object, you couldn't add something to the number literal's prototype.
// Valid javascript
var s = 4.toString();
// Invalid JavaScript code
4.prototype.square = () => 4 * 4;
var square = 4.square();
Just like JavaScript boxes the numeric literal 4 in the call to the toString
method, C# boxes all things that are not objects into an Object
type when putting them into an ArrayList
.
var arrayList = new ArrayList();
arrayList.Add(4); // The value 4 is boxed into a `new Object()` first and then that new object is inserted as the last element in the `ArrayList`.
This involves a certain penalty, as it does in the case of JavaScript as well.
In C#, you can avoid this penalty as C# provides a strongly typed version of the ArrayList
, known as the List<T>
. So it follows that you cannot put anything into a List<T>
; just T
types.
However, I assume from your question's text that you already knew that C# had generic structures for strongly typed items. And your question was to have a JavaScript like data structure exhibiting the semantics of typelessness and elasticity, like the JavaScript Array
object. In this case, the ArrayList
comes closest.
It is also clear from your question that your interest was academic and not to use the structure in a production application.
So, I assume that for a production application, you would already know that a generic / strongly typed data structure (List<T>
for example) is better performing than its non-typed one (ArrayList
for example).
I don't understand what you are doing with the for loop. You are merely iterating over every element and assigning to the first element you encounter. If you're trying to push to a list go with the above answer that states there is no such thing as pushing to a list. That really is getting the data structures mixed up. Javascript might not be setting the best example, because a javascript list is really also a queue and a stack at the same time.
This is acceptable as assigning to an array. But if you are asking for pushing, I am pretty sure its not possible in array. Rather it can be achieved by using Stack, Queue or any other data structure. Real arrays doesn't have such functions. But derived classes such as ArrayList have it.
Your question is a little off the mark. In particular, you say "that the element needs to be added into the first empty slot in an array, lie (sic) a Java push function would do."
The verb "Push" is not something that is used with an Array in any language that I know of except JavaScript. I suspect that it's only in JavaScript because it could be there (since JavaScript is a completely dynamic language). I'm pretty sure it wasn't designed in intentionally.
A JavaScript-style Push operation in C# could be written in this somewhat inefficient manner:
int [] myArray = new int [] {1, 2, 3, 4};
var tempList = myArray.ToList();
tempList.Add(5);
myArray = tempList.ToArray(); //equiv: myArray.Push(5);
"Push" is used in some types of containers, particularly Stacks, Queues and Deques (which get two pushes - one from the front, one from the back). I urge you not to include Push as a verb in your explanation of arrays. It adds nothing to a CS student's vocabulary.
In C#, as in most traditional procedural languages, an array is a collection of elements of a single type, contained in a fixed length contiguous block of memory. When you allocate an array, the space for every array element is allocated (and, in C# those elements are initialized to the default value of the type, null for reference types).
In C#, arrays of reference types are filled with object references; arrays of value types are filled with instances of that value type. As a result, an array of 4 strings uses the same memory as an array of 4 instance of your application class (since they are both reference types). But, an array of 4 DateTime instances is significantly longer that of an array of 4 short integers.
In C#, an instance of an array is an instance of System.Array, a reference type. Arrays have a few properties and methods (like the Length property). Otherwise, there isn't much you can do with an array: you can read (or write) from (or to) individual elements using an array index. Arrays of type T also implement IEnumerable<T>
, so you can iterate through the elements of an array.
Arrays are mutable (the values in an array can be written to), but they have a fixed length - they can't be extended or shortened. They are ordered, and they can't be re-arranged (except by swizzling the values manually).
C# arrays are covariant. If you were to ask the C# language designers, this would be the feature they regret the most. It's one of the few ways you can break C# type safety. Consider this code (assuming that Cat and Dog classes inherit from Animal):
Cat[] myCats = new Cat[]{myCat, yourCat, theirCat};
Animal[] animals = (Animal[]) myCats; //legal but dangerous
animals[1] = new Dog(); //heading off the cliff
myCats[1].Speak(); //Woof!
That "feature" is the result of the lack of generic types and explicit covariance/contravariance in the initial version of the .NET Framework and the urge to copy a Java "feature".
Arrays do show up in many core .NET APIs (for example, System.Reflection). They are there, again, because the initial release did not support generic collections.
In general, an experienced C# programmer will not use many arrays in his applications, preferring to use more capable collections such as List<T>
, Dictionary<TKey, TValue>
, HashSet<T>
and friends. In particular, that programmer will tend to pass collections around using IEnumerable<T>
an interface that all collections implement. The big advantage of using IEnumerable<T>
as parameters and return types (where possible and logical) is that collections accessed via IEnumerable<T>
references are immutable. It's kinda-sorta like using const
correctly in C++.
One thing you might consider adding in to your lectures on arrays - after everyone has mastered the basics - is the new Span<T>
type. Spans may make C# arrays useful.
Finally, LINQ (Language Integrated Query) introduced a lot of functionality to collections (by adding Extension Methods to IEnumerable<T>
). Make sure your student do not have a using System.Linq;
statement up at the top of their code - mixing LINQ in to a beginning student's class on arrays would bewilder him or her.
BTW: what kind of class is it you teach? At what level?