- Home /
Invalid behavior of C# code while using IList on iOS
I have found a strange behavior in my Unity3D project written in C# and built for iPhone.
Sometimes IList objects (objects of types which implement IList interface) lose information about elements types. During my research I figured out that it occurs when typecast to IList had a place (f.e. from ArrayList to IList) and ToString() method was called.
Here is a simple test method I called from Start() method of my script.
public void IListToStringTest() {
ConsolePrintln("---\nIListToStringTest");
IList list = new ArrayList(); // <-- ARRAYLIST IS TYPECASTED TO ILIST
list.Add(1);
ConsolePrintln("Before \"listString = list.ToString()\"");
ConsolePrintln("list[0] = " + list[0].ToString());
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
ConsolePrintln("list[0] = " + list[0].ToString());
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
ConsolePrintln("list[0] = " + list[0].ToString());
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
string listString = list.ToString();
ConsolePrintln("After \"listString = list.ToString()\"");
ConsolePrintln("list[0] = " + list[0].ToString()); // <-- TYPE INFO IS ALREADY LOST
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
ConsolePrintln("list[0] = " + list[0].ToString());
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
ConsolePrintln("list[0] = " + list[0].ToString());
ConsolePrintln("list[0].GetType().ToString() = " + list[0].GetType().ToString());
ConsolePrintln("listString = " + listString);
int intFromList = (int)list[0]; // <-- InvalidCastException IS THROWN HERE
ConsolePrintln("intFromList = " + intFromList);
}
And here is an output:
---
IListToStringTest
Before "listString = list.ToString()"
list[0] = 1
list[0].GetType().ToString() = System.Int32
list[0] = 1
list[0].GetType().ToString() = System.Int32
list[0] = 1
list[0].GetType().ToString() = System.Int32
After "listString = list.ToString()"
list[0] = System.Collections.ArrayList
list[0].GetType().ToString() = System.String
list[0] = System.Collections.ArrayList
list[0].GetType().ToString() = System.String
list[0] = System.Collections.ArrayList
list[0].GetType().ToString() = System.String
listString = System.Collections.ArrayList
System.InvalidCastException: Cannot cast from source type to destination type.
at PPSSerializingTest.IListToStringTest () [0x001ba] in /Users/vlad/Projects/Unity/PPSSerializingTest/Assets/PPSSerializingTest.cs:171
at PPSSerializingTest.Start () [0x00000] in /Users/vlad/Projects/Unity/PPSSerializingTest/Assets/PPSSerializingTest.cs:16
As you can see after list.ToString() was called information about element was lost.
Note, that this issue is not reproduced every time. I reproduced it on iPhone 4s (iOS 5.01) after 4 or more launches from Xcode (without rebuilding it from Unity).
I assume this issue can be related to full-aot compiler mode, because on Android this code works well.
I'm using Unity 3.5.0b6, license type: Unity, iPhone, Android.
Is there any idea why this may happen?
Thanks in advance!
PS* I have opened another thread about issue that can be related to this: http://answers.unity3d.com/questions/233437/c-list-to-ilist-cast-bug.html
Answer by Kryptos · Mar 29, 2012 at 09:57 PM
You should not use ArrayList but generic version of List (System.Collections.Generic).
Can you please explain, why do you think so? I don't know exactly the type of elements, because I use ArrayList to store deserialization result, moreover elements can have different types.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers