【问题标题】:UnorderedEquals method to compare 2 lists fails on Boolean values比较 2 个列表的 UnorderedEquals 方法在布尔值上失败
【发布时间】:2018-10-17 07:52:52
【问题描述】:

我使用 UnorderedEquals 扩展来比较 2 个列表。它工作得很好,除了唯一的区别是布尔值。这是比较方法:

    public static bool UnorderedEquals<T>( this IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer )
    {
        var d = new Dictionary<T, int>( comparer );
        foreach( T s in list1 )
        {
            if( d.ContainsKey( s ) )
            {
                d[s]++;
            }
            else
            {
                d.Add( s, 1 );
            }
        }
        foreach( T s in list2 )
        {
            if( d.ContainsKey( s ) )
            {
                d[s]--;
            }
            else
            {
                return false;
            }
        }
        return d.Values.All( c => c == 0 );
    }

这是我的类和 IEqualityComparer:

    public class SelectedEntities
    {
        public int Id { get; set; }
        public bool IsDelegator { get; set; }
        public bool IsDelegate { get; set; }
    }

    public class SelectedEntitiesEqualityComparer : IEqualityComparer<SelectedEntities>
    {
        public bool Equals( SelectedEntities x, SelectedEntities y )
        {
            if( object.ReferenceEquals( x, y ) )
                return true;
            if( x == null || y == null )
                return false;
            return x.Id.Equals( y.Id );
        }

        public int GetHashCode( SelectedEntities obj )
        {
            return obj.Id.GetHashCode( );
        }
    }

使用此代码,我应该能够通过运行以下命令获得错误值:

    private bool CompareLists( )
    {
        bool result = false;

        var list1 = new List<SelectedEntities>( );
        var list2 = new List<SelectedEntities>( );

        list1.Add( new SelectedEntities { Id = 1, IsDelegator = false, IsDelegate = true } );
        list1.Add( new SelectedEntities { Id = 2, IsDelegator = false, IsDelegate = true } );

        list2.Add( new SelectedEntities { Id = 1, IsDelegator = false, IsDelegate = true } );
        list2.Add( new SelectedEntities { Id = 2, IsDelegator = false, IsDelegate = false } ); // this is different

        result = list1.UnorderedEquals( list2, new SelectedEntitiesEqualityComparer( ) );

        return result;
    }

如果我将任何布尔值更改为两个列表之间的不同,它总是返回 true。奇怪。

【问题讨论】:

    标签: c# list compare iequalitycomparer


    【解决方案1】:

    您的comparer 没有考虑所有字段。 目前您只比较IdIsDelegatorIsDelegate 呢?

    你应该添加它们:

    public class SelectedEntitiesEqualityComparer : IEqualityComparer<SelectedEntities>
    {
        public bool Equals( SelectedEntities x, SelectedEntities y )
        {
            if( object.ReferenceEquals( x, y ) )
                return true;
            if( x == null || y == null )
                return false;
            return x.Id.Equals( y.Id ) && 
                   x.IsDelegator.Equals(y.IsDelegator) &&
                   x.IsDelegate.Equals(y.IsDelegate);
        }
    
        public int GetHashCode( SelectedEntities obj )
        {
            return obj.Id.GetHashCode( )^
                   obj.IsDelegator.GetHashCode()^
                   obj.IsDelegate.GetHashCode();
        }
    }
    

    顺便说一句GetHashCode 的这种实现可能不是最佳的。有关这方面的良好做法,请查看What is the best way to implement this composite GetHashCode()


    注意 您对UnorderedEquals 的实现可以缩短为:

    return list1.Count() == list2.Count() &&
           list1.All(e=> list2.Contains(e, comparer));
    

    【讨论】:

    • 天哪……我怎么会错过呢?非常感谢@Ofir Winegarten 的帮助!
    • UnorderedEquals 的缩短版太棒了!谢谢!
    猜你喜欢
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多