Неверное поведение кода C # при использовании IList в Unity3d на iOS - PullRequest
1 голос
/ 29 марта 2012

Я обнаружил странное поведение в своем проекте Unity3D, написанном на C # и построенном для iPhone.
Иногда Объекты IList (объекты типов, которые реализуют интерфейс IList) теряют информацию о типах элементов.В ходе моего исследования я выяснил, что это происходит, когда тип имеет место для IList (например, от ArrayList до IList ) и ToString () .1010 *

Вот простой метод теста, который я вызвал из Start () метод моего скрипта.

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 () вызвана информация об элементе была потеряна.

Обратите внимание, что эта проблема не воспроизводится каждый раз.Я воспроизвел его на iPhone 4s (iOS 5.01) после 4 или более запусков из Xcode (без перекомпоновки из Unity).
Я использую Unity 3.5.0b6, тип лицензии: Unity, iPhone, Android.

Есть ли идеи, почему это может произойти?

Заранее спасибо!

PS * Я открыл еще одну ветку о проблеме, которая может быть связана с этим: C # List в IList ошибка приведения в Unity3d

1 Ответ

0 голосов
/ 29 марта 2012

На основании того, что я вижу.Это именно то поведение, которое должно произойти.

string listString = list.ToString ();

Преобразует коллекцию, которая является IList, в string, поэтому строковое значение liststring будет string значением, равным System.Collections.IList , если я не ошибаюсь.

Вы в основном делаете Type.ToString() в этой строке.Что касается причины, по которой кажется, что тип в ArrayList меняется, я, честно говоря, не могу этого объяснить, я подозреваю, что происходит что-то не зловещее.

string listString = list.ToString ();

может легко стать

string listString = list [0] .ToString ();

Это будет по крайней мере установить значение liststring к первому элементу списка ArrayList

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...