我使用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。奇怪。
答案 0 :(得分:2)
您的comparer
未考虑所有字段。
目前,您仅比较Id
。 IsDelegator
和IsDelegate
呢?
您应该添加它们:
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();
}
}
BTW 这种GetHashCode
的实现可能不是最佳的。有关与此相关的良好做法,请查看What is the best way to implement this composite GetHashCode()
注意
您可以将UnorderedEquals
的实现简化为:
return list1.Count() == list2.Count() &&
list1.All(e=> list2.Contains(e, comparer));