我有一个concurrentbag集合,我也添加了项目..现在我最终可能会有多个项目相同(由3个字符串属性定义相同)
我不确定两件事。
基本上,目标是让cityProcessor属性NotFoundCities可能包含重复项,然后在addcities方法中只获取非重复列表
public class CityProcesor
{
public ConcurrentBag<CityNotFound> NotFoundCities { get; set; }
public void AddCities()
{
var nonDups = NotFoundCities.ToList().Distinct(new NotFoundCityComparer());
}
}
public class CityNotFound
{
public string Name { get; set; }
public string RegionName { get; set; }
public string CountryCode { get; set; }
}
public class NotFoundCityComparer : IEqualityComparer<CityNotFound>
{
public bool Equals(CityNotFound city1, CityNotFound city2)
{
return city1.Name == city2.Name && city1.RegionName == city2.RegionName && city1.CountryCode == city2.CountryCode;
}
public int GetHashCode(CityNotFound obj)
{
return 1; //TODO: fix
}
}
答案 0 :(得分:1)
您可以使用Jon Skeet DistinctBy中的MoreLinq扩展方法,而不是实现Equals
和GetHashCode
,该方法既可以作为源代码使用,也可以作为{{3}使用}。
有了DistinctBy,你可以写:
var noDups=myCities.DistinctBy(city=>
new {city.Name,city.RegionName,city.CountryCode});
要在比较器中实现GetHashCode
,您可以使用任何将返回适度宽范围值的算法 - 它不必是唯一的。
使用ReSharper的模板创建了以下代码段,并对每个属性的哈希码进行异或,例如:
public override int GetHashCode()
{
unchecked
{
var hashCode = (Name != null ? Name.GetHashCode() : 0);
hashCode = (hashCode*397) ^ (RegionName != null ? RegionName.GetHashCode() : 0);
hashCode = (hashCode*397) ^ (CountryCode != null ? CountryCode.GetHashCode() : 0);
return hashCode;
}
}
答案 1 :(得分:0)
我使用以下方法生成哈希值。我无法记住我在哪里找到了基于它的算法(可能在StackOverflow上的某个地方),但我将它放入以下实用程序类和方法中,以便能够从多个字段/属性创建哈希值:
public static class HashGenerator
{
private const int seed = 29;
private const int factor = 31;
/// <summary>
/// Method to generate a hash code from multiple objects.
/// This can be used when overriding GetHashCode by passing in an object's key fields
/// </summary>
public static int GetHashCodeFromMany(params object[] objects)
{
unchecked
{
int hashCode = seed;
int length = objects.Length;
for (int counter = 0; counter < length; counter++)
{
object obj = objects[counter];
if (obj != null)
{
int objHashCode = obj.GetHashCode();
hashCode *= factor + objHashCode;
}
}
return hashCode;
}
}
}
然后可以这样使用:
public override int GetHashCode()
{
return HashGenerator.GetHashCodeFromMany(Name, RegionName, CountryCode);
}
最好将它与不可变对象一起使用,否则更改关键字段/属性可能会对使用哈希的集合类造成严重破坏。