我正在努力让FarseerPhysics在MonoTouch中编译。当我在System.Collections.Generic中使用HashSet时它工作正常,但是Farseer有自己的用于Xbox 360和Windows Phone的Hashset类,所以我认为为IPHONE包含该hashset也是有意义的。
这是Farseer哈希集代码:
#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添加到Farseer hashset类文件中的#if时会出现两个问题。
第一个是我在声明中得到错误,其中编译器说HashSet是System.Collections.Generic.HashSet和FarseerPhysics.Common.HashSet之间的一个不明确的引用。 Visual Studios编译器中不会发生此错误。我怀疑这是因为MonoTouch确实实现了Hashset,其中Xbox 360和Windows Phone .Net API都没有。不太确定为什么没有任何一个的hashset,但我怀疑我最好使用hashset的Farseers versio。
另一个问题是,如果我在iPhone设备上运行应用程序时显式设置声明使用FarseerPhysics.Common.Hashset(即新的FarseerPhysics.Common.HashSet();),我会收到错误
'尝试JIT编译方法'System.Collections.Generic.Dictionary'2:.ctor()' 使用--aot-only运行时。\ n'
我还应该指出,在模拟器中不会发生此错误,仅在实际设备上发生。
答案 0 :(得分:2)
第一个问题,含糊不清的引用,是因为现在你有两个叫做HashSet的类,你的类正在使用它,而你没有指定你想要的那个。您可以删除using System.Collections.Generic;
行,或在文件顶部添加using HashSet = FarseerPhysics.Common.HashSet;
语句。这将使编译器知道哪一个具体使用。
您获得的JIT编译错误是monotouch的一些限制之一:您无法在字典键中使用值类型,因为单声道编译器将尝试实例化比较器对象。有关详细信息,请查看此处:http://monotouch.net/Documentation/Limitations(搜索“值类型作为字典键”)。
要解决此问题,您需要在新类型中实现IEqualityComparer接口,并向Dictionary(IEqualityComparer)构造函数提供该类型的实例。