Mono中的通用IComparable实现问题

时间:2014-07-07 12:46:59

标签: c# mono unity3d compareto icomparable

此代码在.NET 4.0中成功执行

    public void CompareTest()
    {
        var m1 = new Foo { Order = 1 };
        var m2 = new Foo { Order = 2 };
        var c1 = new Bar { Order = -1 };
        var c2 = new Bar { Order = 3 };
        var list1 = new List<IOrderable> { m1, m2, c1, c2 };
        var list2 = new List<Bar> { c1, c2 };
        list1.Sort();
        list2.Sort();
    }

    public interface IOrderable : IComparable<IOrderable>
    {
        int Order { get; set; }
    }

    public class Foo : IOrderable
    {
        public int Order { get; set; }

        public int CompareTo(IOrderable other)
        {
            return Order.CompareTo(other.Order);
        }
    }

    public class Bar : IOrderable
    {
        public int Order { get; set; }

        public int CompareTo(IOrderable other)
        {
            return Order.CompareTo(other.Order);
        }
    }

但是在Mono 2.6(在Unity3D中)它会引发异常:

ArgumentException: does not implement right interface

它投掷的是第二种(list2.Sort())而不是第一种

我对所有这些比较的东西都是新手,请原谅我,如果我在这里遗漏了一些明显的东西。

为什么抱怨没有实现正确的界面?它已实施。有什么想法在这里发生了什么?为什么它在.NET中工作而在Mono中不工作?

感谢。

编辑:完整堆栈

ArgumentException: does not implement right interface
System.Collections.Generic.Comparer`1+DefaultComparer[ShowEmAll.BetterBehaviourEditor+Bar].Compare (ShowEmAll.Bar x, ShowEmAll.Bar y) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/Comparer.cs:86)
System.Array.compare[Bar] (ShowEmAll.Bar value1, ShowEmAll.Bar value2, IComparer`1 comparer) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1744)
System.Array.qsort[Bar,Bar] (.Bar[] keys, .Bar[] items, Int32 low0, Int32 high0, IComparer`1 comparer) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1721)
System.Array.Sort[Bar,Bar] (.Bar[] keys, .Bar[] items, Int32 index, Int32 length, IComparer`1 comparer) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1674)
Rethrow as InvalidOperationException: The comparer threw an exception.
System.Array.Sort[Bar,Bar] (.Bar[] keys, .Bar[] items, Int32 index, Int32 length, IComparer`1 comparer) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1677)
System.Array.Sort[Bar] (.Bar[] array, Int32 index, Int32 length, IComparer`1 comparer) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1623)
System.Collections.Generic.List`1[ShowEmAll.BetterBehaviourEditor+Bar].Sort () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:568)
ShowEmAll.BetterBehaviourEditor.CompareTest () (at Assets/Vexe/ShowEmAll/Core/Editor/CustomEditors/BetterBehaviourEditor.cs:81)
ShowEmAll.BetterBehaviourEditor.OnEnable () (at Assets/Vexe/ShowEmAll/Core/Editor/CustomEditors/BetterBehaviourEditor.cs:62)

1 个答案:

答案 0 :(得分:2)

首先,这看起来可能是Comparer<T>.Default中的Mono错误,如果TIComparable<Foo>实现了Foo,它应该是一个接口{{1}实现,或T的基本类型。

对于变通方法,有四个选项:

  • T中实施非通用IComparable接口,可能只是委托Bar
  • 的实施
  • CompareTo(IOrder)中实施IComparable<Bar>,可能只是委托Bar的实施
  • 即使其中的每件商品都是CompareTo(IOrder)
  • ,也要始终使用List<IOrder>
  • 指定BarComparer<T> - 我怀疑,您可以非常轻松地使用泛型构建自己的实现。