加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – EqualityComparer.Default不够聪明

发布时间:2020-12-15 07:54:52 所属栏目:百科 来源:网络整理
导读:我正在阅读EqualityComparer T .Default的源代码,发现它并不那么聪明.这是一个例子: enum MyEnum : int { A,B }EqualityComparerMyEnum.Default.Equals(MyEnum.A,MyEnum.B)//is as fast as EqualityComparerint.Default.Equals(0,1)enum AnotherEnum : long
我正在阅读EqualityComparer< T> .Default的源代码,发现它并不那么聪明.这是一个例子:
enum MyEnum : int { A,B }
EqualityComparer<MyEnum>.Default.Equals(MyEnum.A,MyEnum.B)
//is as fast as 
EqualityComparer<int>.Default.Equals(0,1)

enum AnotherEnum : long { A = 1L,B = 2L }
//is 8x slower than
EqualityComparer<long>.Default.Equals(1L,2L)

从EqualityComparer中私有方法的源代码可以看出原因.

private static EqualityComparer<T> CreateComparer()
{
    //non-important codes are ignored
    if (c.IsEnum && (Enum.GetUnderlyingType(c) == typeof(int)))
    {
        return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(EnumEqualityComparer<int>),c);
    }
    return new ObjectEqualityComparer<T>();
}

我们可以看到EqualityComparer< int> .Default,EqualityComparer< MyEnum> .Default和EqualityComparer< long> .Default得到一个明智的比较器,其Equals方法如下所示:

public static bool Equals(int x,int y)
{
    return x == y;  //or return x.Equals(y); here 
                    //I'm not sure,but neither causes boxing
}

public static bool Equals(MyEnum x,MyEnum y)
{
    return x == y;  //it's impossible to use x.Equals(y) here 
                    //because that causes boxing
}

上面两个是聪明的,但EqualityComparer< AnotherEnum> .Default是不吉利的,从我们最终可以看到的方法得到一个ObjectEqualityComparer< T>(),它的Equals方法可能看起来像:

public static bool Equals(AnotherEnum x,AnotherEnum y)
{
    return x.Equals(y);   //too bad,the Equals method is from System.Object
                       //and it's not override,boxing here!
                       //that's why it's so slow
}

我认为这个条件Enum.GetUnderlyingType(c)== typeof(int)是没有意义的,如果枚举的基础类型是int类型,该方法可以将int的默认比较器转换为此枚举.但为什么不能基于长期的枚举?我觉得这不难吗?任何特殊原因?构造像x == y这样的比较器对枚举来说并不那么难,对吧?为什么最后它给出了一个慢的ObjectEqualityComparer< T>对于枚举(即使它正常工作)?

解决方法

我认为负责添加此功能的团队没有令人信服的理由.所有功能都有一个实现成本,其中包括(其中包括)文档,代码和测试的时间.

有一些令人信服的理由说明为什么到目前为止这个特定功能还没有被其他人选中(并且可能永远不会削减IMO):

>它仅适用于非常狭窄的场景(比较由int以外的其他东西支持的枚举,并在某些内循环中执行此操作)>如果它导致您出现问题,可以使用非常直接且可发现的解决方案(编写您自己的比较器)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读