System.Int32是否有内置的IEqualityComparer <t>?

时间:2018-06-14 18:36:26

标签: c# .net xamarin.ios .net-standard

我们目前正在使用EqualityComparer<TKey>.Default作为初始化通用字典的默认方式。但是,当字典的键是int类型时,它会在Xamarin.iOS上崩溃并出现以下错误(但在我尝试过的许多其他平台上都有效):

  

在仅以aot模式运行时尝试JIT编译方法Lucene.Net.Support.LurchTable2<Lucene.Net.Facet.Taxonomy.FacetLabel, Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyReader/Int32Class>:InternalInsert<Lucene.Net.Support.LurchTable2/Add2Info<Lucene.Net.Facet.Taxonomy.FacetLabel, Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyReader/Int32Class>> (int,Lucene.Net.Facet.Taxonomy.FacetLabel,int&,Lucene.Net.Support.LurchTable/Add2Info<Lucene.Net.Facet.Taxonomy.FacetLabel, Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyReader/Int32Class>)。有关详细信息,请参阅https://developer.xamarin.com/guides/ios/advanced_topics/limitations/

     

at Lucene.Net.Support.LurchTable2 [TKey,TValue] .Insert [T](TKey key,T&amp; value)&lt; 0x2570f48 + 0x000e0&gt;在&LT; 063e095c95d945a4ace32ab83d1227eb#2ae0fea9ea4eacaef83bf2e9713bb8ea&GT;:在(包装未知)System.Object.gsharedvt_in()在Lucene.Net.Support.LurchTable2 [TKEY的,TValue] .AddOrUpdate(TKEY的键,TValue的addValue,Lucene.Net.Support.KeyValueUpdate2 0 [TKey,TValue] fnUpdate)&lt; 0x232824c + 0x0013b&gt;在&lt; 063e095c95d945a4ace32ab83d1227eb#2ae0fea9ea4eacaef83bf2e9713bb8ea&gt;:0 at Lucene.Net.Facet.Taxonomy.LRUHashMap2 [TKey,TValue] .Put(TKey key,TValue value)&lt; 0x2c487f8 + 0x0015b&gt;在&lt; 79d3a7b905954d0993025c09c5d087ce#2ae0fea9ea4eacaef83bf2e9713bb8ea&gt;:0在Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyReader.GetOrdinal(Lucene.Net.Facet.Taxonomy.FacetLabel cp)&lt; 0x2c51970 + 0x0019b&gt;在&lt; 79d3a7b905954d0993025c09c5d087ce#2ae0fea9ea4eacaef83bf2e9713bb8ea&gt;:0在Lucene.Net.Facet.Taxonomy.Int32TaxonomyFacets.GetTopChildren(System.Int32 topN,System.String dim,System.String [] path)&lt; 0x2c481dc + 0x0008f&gt;在&LT; 79d3a7b905954d0993025c09c5d087ce#2ae0fea9ea4eacaef83bf2e9713bb8ea&GT;:0在Login.MyMB.Lucene.Client.LuceneArticoliSearcher.GetListaArticoloXRicercaAvanzataConRicercaSemplice(System.Collections.Generic.List1 [T] listParametri)LT; 0x224add0 + 0x001bb&GT;在&LT; 8f49891e0f0546e185aba7424d294ef7#2ae0fea9ea4eacaef83bf2e9713bb8ea&GT;:0在Login.MyMB.Lucene.Client.LuceneArticoliSearcher.GetListaArticoloConRicercaSemplice(System.Collections.Generic.List1 [T] listParametri)LT; 0x224afbc + 0x0009f&GT;在&LT; 8f49891e0f0546e185aba7424d294ef7#2ae0fea9ea4eacaef83bf2e9713bb8ea&GT;:0在MyMB.Forms.RicercaLucene.RicercaArticoloLucene.GetListaArticoliXRicercaSemplice(Login.MyMB.Interface.IAmbiente AMBIENTE,Login.MyMB.Lucene.Client.LuceneArticoliSearcher LAS,System.Collections.Generic.List`1 [ T] ListParametri,System.Boolean isAbilitataRicercaBarcode)&lt; 0xe47fc0 + 0x000e7&gt; in:0 ................................

在链接https://docs.microsoft.com/it-it/xamarin/ios/internals/limitations,我发现问题原因(我想......):

  

值类型作为字典键使用值类型作为Dictionary<TKey, TValue>键是有问题的,因为默认的Dictionary构造函数尝试使用EqualityComparer<TKey>.Default。反过来,EqualityComparer<TKey>.Default尝试使用Reflection来实例化实现IEqualityComparer<TKey>接口的新类型。这适用于引用类型(因为反射+创建新类型步骤被跳过),但对于值类型,一旦您尝试在设备上使用它,它会很快崩溃和烧毁。   解决方法:在新类型中手动实现IEqualityComparer<TKey>接口,并向Dictionary<TKey, TValue>IEqualityComparer<TKey>)构造函数提供该类型的实例。

问题

是否有内置的跨平台方式来创建默认IEqualityComparer<int>?我试图避免创建像这样的课程

private class Int32EqualityComparer : IEqualityComparer<int>
{
    bool IEqualityComparer<int>.Equals(int x, int y)
    {
        return x.Equals(y);
    }

    int IEqualityComparer<int>.GetHashCode(int obj)
    {
        return obj.GetHashCode();
    }
} 

只是为了解决这个错误。

2 个答案:

答案 0 :(得分:4)

您可以通过搜索API reference来确定.NET Standard中没有IEqualityComparer<int>的实现。

如果您打算自己实施IEqualityComparer<T>,那么将T限制为IEquatable<T>的通用实现可能是值得的,这样您就可以覆盖多种类型而不仅仅是{{1} }}。建议所有值类型按Framework design guidelines实现int

答案 1 :(得分:2)

它看起来不像,the list of derived types on IEqualityComparer<T>'s documentation for .NET Standard 2.0没有为整数列出任何内容。