How similar are they? (I haven’t used a C# List yet.)
What is the performance difference between a List and a C# array? If you only need to modify the array once, or infrequently, is it better to convert the List to an array, as described with JS Arrays on this page:
Not sure on the specific number ( you could always test this in code), but an array will be faster than a list. A list is basically a wrapped array with lots of built in features. You can move between them in C#
List<GameObject> list = new List<GameObject>();
GameObject[] array = list.ToArray();
List<GameObject> list2 = new List<GameObject>(array.Length);
list2.AddRange(array);
If you do not need the “features” of a list, then use an array (things like autosizing).
Can you even access members of the array using the [ ] syntax? I’m not seeing that in the MSDN docs. But that seems pretty stupid - if it’s going to be slower than an array, it ought to at least be able to do everything an array can do.
Unless you’re building a game with very large amounts of big array operations (thousands upon thousands of array-accesses per frame), I don’t think your choice of array type should be given by performance. Perhaps the iPhone would be an exception to that, but there List<> is not supported, so your question doesn’t apply there.
As a C# user, I tend to use List<> for most dynamic arrays, as they make for more readable code than ArrayList (due to the casting). The only reason to convert the list to built-in for me was when the array needed to be exposed in the editor, but I believe that in 2.6.1, List<> can now also be viewed through the inspector.
Anyway, should you want to convert to built-in anyway, the function for that is called ToArray and is listed on the MSDN:
Excellent. That filled in some of the holes in my knowledge. Microsoft should pay him to write their documentation - his is actually readable by human beings! :o
In .Net, you can never cast an array to a higher derivation than it was created as:
string[] strs = new string[1];
strs[0] = "blob";
object[] obs = (object[]) strs; // works, as object is a base class of string
string[] str2 = (string[]) obs; // works, as the array was originally created as a string[]
object[] obs = new object[1];
obs[0] = "blob";
string[] strs = (string[]) obs; // throws an InvalidCastException, because obs was created as an object[]
In other words, if you create an array of type X, you will never be able to cast a reference to that array to a derived type of X.
This means that if you implement a function that returns a built-in array, it’s a good idea to create that array of the highest known type. For instance, the Unity function FindObjectsOfType(Type t) creates an array of ‘t’ and its return value can be cast to a t[ ].
Unfortunately, not every function in Unity does this. The most annoying exception being GetComponentsInChildren. This function creates its return array as a Component[ ], so it can never be cast to an array of the type you requested of it and you need to do an element-by-element conversion.
I submitted a bug report requesting a fix for this several months ago, but it is still open, so I don’t think it is considered high priority ;).
Thank you for that explanation, tomvds. It seems very weird to me that such a “history” exists. Is there a good reason why it works like that? It doesn’t seem particularly well-suited to programming.
However, this does work, so I guess it’s what I’ll use, unless someone has something cleaner:
I think it may be because when you cast to a derived type of the original, there is no guarantee that all elements of the array are of the derived class, except by testing all the elements one-by-one. Since that is a relatively expensive operation, they only allow casting to base types, which can be done very fast. All the elements of the array are guaranteed to be of the base type and they need not be checked at all.
KrankyBoyGames, I was going through how other people convert between regular array and the typed List in C# (and back) and was very happy to see your super-concise example here, and that it matches how I do it. Confirmation always feels good.
I know it’s been over a year since you posted this but, just wanted to say thanks for putting both directions of conversion, in one nice code example!