1

我正在努力让 FarseerPhysics 在 MonoTouch 中进行编译。当我在 System.Collections.Generic 中使用 HashSet 时它工作得很好,但是 Farseer 有它自己的用于 Xbox 360 和 Windows Phone 的 Hashset 类,所以我认为为 IPHONE 也包含该哈希集是有意义的。

这是 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 哈希集类文件中的#if 时,有两个问题。

首先是我在声明中遇到错误,编译器说 HashSet 是 System.Collections.Generic.HashSet 和 FarseerPhysics.Common.HashSet 之间的模棱两可的引用。在 Visual Studios 编译器中不会发生此错误。我怀疑这是因为 MonoTouch 确实实现了 Hashset,其中 Xbox 360 和 Windows Phone .Net API 也没有。不太清楚为什么其中任何一个都没有哈希集,但我怀疑对我来说最好使用哈希集的 Farseers 版本。

另一个问题是,如果我在 iPhone 设备上运行应用程序时明确设置声明以使用 FarseerPhysics.Common.Hashset(即 new FarseerPhysics.Common.HashSet();),我会收到错误消息

'在使用 --aot-only 运行时尝试 JIT 编译方法'System.Collections.Generic.Dictionary'2:.ctor()'。\n'

我还应该指出,这个错误不会发生在模拟器中,只发生在实际设备上。

4

1 回答 1

2

第一个问题,引用不明确,是因为现在您有两个名为 HashSet 的类正在被您的类使用,并且您没有指定您想要哪个类。您可以删除该using System.Collections.Generic;行,或using HashSet = FarseerPhysics.Common.HashSet;在文件顶部添加一条语句。这将使编译器知道具体使用哪一个。

您遇到的 JIT 编译错误是 monotouch 的一些限制之一:您不能真正在字典键中使用值类型,因为 mono 编译器将尝试实例化比较器对象的方式。有关更多信息,请查看此处: http: //monotouch.net/Documentation/Limitations(搜索“作为字典键的值类型”)。

To work around this issue, you need to implement the IEqualityComparer interface in a new type and provide an instance of that type to the Dictionary(IEqualityComparer) constructor.

于 2011-05-26T13:37:44.863 回答