#c# #iphone #xamarin.ios #hashset #farseer
#c# #iPhone #xamarin.ios #hashset #дальновидящий
Вопрос:
Я работаю над тем, чтобы заставить FarseerPhysics компилироваться в MonoTouch. Он отлично работает, когда я использую HashSet в системе.Коллекции.Общий, однако у Farseer есть свой собственный класс Hashset, который он использует для Xbox 360 и Windows Phone, поэтому я подумал, что имеет смысл также включить этот hashset для IPHONE.
Это код Farseer hashset:
#if WINDOWS_PHONE || XBOX || IPHONE
//TODO: FIX
using System;
using System.Collections;
using System.Collections.Generic;
namespace FarseerPhysics.Common
{
public class HashSet<T> : ICollection<T>
{
private Dictionary<T, short> _dict;
public HashSet(int capacity)
{
_dict = new Dictionary<T, short>(capacity);
}
public HashSet()
{
_dict = new Dictionary<T, short>();
}
// Methods
#region ICollection<T> Members
public void Add(T item)
{
// We don't care for the value in dictionary, Keys matter.
_dict.Add(item, 0);
}
public void Clear()
{
_dict.Clear();
}
public bool Contains(T item)
{
return _dict.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(T item)
{
return _dict.Remove(item);
}
public IEnumerator<T> GetEnumerator()
{
return _dict.Keys.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _dict.Keys.GetEnumerator();
}
// Properties
public int Count
{
get { return _dict.Keys.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
#endregion
}
}
#endif
Они используются как таковые:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using FarseerPhysics.Collision;
using FarseerPhysics.Common;
using FarseerPhysics.Controllers;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
class World
{
(...)
private HashSet<Body> _bodyAddList = new HashSet<Body>();
private HashSet<Body> _bodyRemoveList = new HashSet<Body>();
private HashSet<Joint> _jointAddList = new HashSet<Joint>();
private HashSet<Joint> _jointRemoveList = new HashSet<Joint>();
}
При добавлении IPHONE в #if в файле класса Farseer hashset class возникают две проблемы.
Во-первых, я получаю ошибку в объявлениях, где компилятор говорит, что HashSet является неоднозначной ссылкой между System.Коллекции.Универсальный.HashSet и FarseerPhysics.Обычный.HashSet. Эта ошибка не возникает в компиляторе Visual Studios. Я подозреваю, что это потому, что MonoTouch реализует Hashset для Xbox 360 и Windows Phone.В Net API нет ни того, ни другого. Не совсем уверен, почему для любого из них нет hashset, но я подозреваю, что для меня было бы лучше использовать версию Farseers для hashset.
Другая проблема заключается в том, что если я явно настрою объявление на использование FarseerPhysics.Обычный.Hashset (т. е. новая физика дальнего видения.Обычный.HashSet();) при запуске приложения на устройстве iPhone я получаю сообщение об ошибке
«Попытка JIT-компиляции метода»System.Коллекции.Generic.Dictionary’2:.ctor()’ при запуске с —aot-only.n’
Я должен также указать, что эта ошибка возникает не в симуляторе, а только на реальном устройстве.
Ответ №1:
Первая проблема с неоднозначной ссылкой заключается в том, что теперь у вас есть два класса с именем HashSet, которые используются вашим классом, и вы не указываете, какой из них вам нужен. Вы можете удалить using System.Collections.Generic;
строку или добавить using HashSet = FarseerPhysics.Common.HashSet;
инструкцию в начало файла. Это позволит компилятору узнать, какой из них конкретно использовать.
Ошибка компиляции JIT, которую вы получаете, является одним из нескольких ограничений monotouch: вы не можете использовать типы значений в ключах словаря из-за способа, которым компилятор mono попытается создать экземпляр объекта сравнения. Для получения дополнительной информации посмотрите здесь: http://monotouch.net/Documentation/Limitations (найдите «типы значений как ключи словаря»).
Чтобы обойти эту проблему, вам необходимо реализовать интерфейс IEqualityComparer в новом типе и предоставить экземпляр этого типа конструктору Dictionary (IEqualityComparer).