2012-03-29 15 views
1

我在Unity3D项目中使用C#编写并为iPhone构建了一个奇怪的行为。
有时 IList对象(实现IList接口的类型的对象)会丢失有关元素类型的信息。在我的研究中,我发现它发生在对IList进行类型转换时发生(从ArrayListIList)和ToString()方法被调用。在iOS的Unity3d中使用IList时C#代码的行为无效

这是我从开始()我的脚本调用的一种简单的测试方法。

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); 
} 

这里是输出:

--- 
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 

正如你可以后list.ToString看到()被称为关于元素的信息丢失。

请注意,这个问题并不是每次都会重现。我在4次或更多次从Xcode启动(不需要从Unity重建它)后将其复制到iPhone 4s(iOS 5.01)上。
我正在使用Unity 3.5.0b6,许可证类型:Unity,iPhone,Android。

有什么想法为什么会发生这种情况?

在此先感谢!

PS *我已经打开另一个线程有关的问题,可以与此有关:C# List<object> to IList cast bug in Unity3d

+0

1的详细描述中的第一个元素。快速测试发现它不能在我的机器上重现。我知道这很烦人。 ConsolePrintln方法内部完成了什么? – Kay 2012-03-29 15:09:05

+0

FWIW可以在Mono和MonoTouch中使用 – poupou 2012-03-29 15:13:09

+0

ConsolePrintln非常简单,只包含'UnityEngine.Debug.Log(文本);' – 2012-03-29 15:24:31

回答

0

基于我所看到的。这正是应该发生的行为。

string listString = list.ToString();

该功能可将收集这是一个IListstring所以liststring字符串值将string值等于System.Collections.IList如果我没有记错的话。

你基本上是在做那条线上的Type.ToString()。至于它出现在ArrayList中的类型正在发生变化的原因,我诚实地无法解释这一点,我怀疑某些非恶意事件正在发生。

string listString = list.ToString();

很容易成为

串listString =列表[0]。的ToString();

这将的liststring值至少设定为ArrayList列表