gpt4 book ai didi

c# - 如何正确实现 HashSet 的 IEqualityComparer?

转载 作者:行者123 更新时间:2023-11-30 22:39:20 24 4
gpt4 key购买 nike

我正在编写一些代码,将 LDAP 属性名称映射到友好名称并返回。只有简单的类称为 DirectoryProperty:

public class DirectoryProperty
{
public string Id { get; set; }
public string Name { get; set; }
public string HelpText {get; set; }

public DirectoryProperty(string id, string name)
{
Id = id;
Name = name;
}
}

然后我有代码使用 HashSet 来构建这些对象的集合。我提供了一组固定的属性,但我想允许其他人添加他们自己的项目。集合似乎是一个很好的结构,因为当您查询 LDAP 时,您不希望有重复的属性,这也适用于用户从属性列表中进行选择的 UI。

public class PropertyMapper
{
readonly HashSet<DirectoryProperty> props = new HashSet<DirectoryProperty>(new DirectoryPropertyComparer());

public PropertyMapper() // Will eventually pass data in here
{
props.Add(new DirectoryProperty("displayName", "Display Name"));
props.Add(new DirectoryProperty("displayName", "Display Name")); //err
props.Add(new DirectoryProperty("xyz", "Profile Path")); //err
props.Add(new DirectoryProperty("samAccountName", "User Account Name"));
props.Add(new DirectoryProperty("mobile", "Mobile Number"));
props.Add(new DirectoryProperty("profilePath", "Profile Path"));
}

public List<string> GetProperties()
{
return props.Select(directoryProperty => directoryProperty.Id).OrderBy(p => p).ToList();
}

public List<string> GetFriendlyNames()
{
return props.Select(directoryProperty => directoryProperty.Name).OrderBy(p => p).ToList();
}
}

如您所见,我现在在构造函数中有 2 个问题数据项。第一个是明显的重复项,另一个是基于 DirectoryProperty 的 Name 属性的重复项。

我对 IEqualityComparer 的初始实现如下所示:

class DirectoryPropertyComparer : IEqualityComparer<DirectoryProperty>
{
public bool Equals(DirectoryProperty x, DirectoryProperty y)
{
if (x.Id.ToLower() == y.Id.ToLower() || x.Name.ToLower() == y.Name.ToLower())
{
return true;
}

return false;
}

public int GetHashCode(DirectoryProperty obj)
{
return (obj.Id.Length ^ obj.Name.Length).GetHashCode();
}
}

我能做些什么来确保 DirectoryProperty 的 Id 和 Name 属性都经过唯一性检查以确保捕获基于其中任何一个的重复项?我在这里可能太严格了,我接受了我现有的代码,因为它似乎可以处理重复的 Id,但我有兴趣了解更多相关信息。

最佳答案

不清楚你到底想做什么:

  • 如果它们的名称​​或它们的 ID 相同,则您的相等方法认为两个值相等
  • 您的 GetHashCode 方法包含两个值,因此(除了意外冲突)您只有在两个名称和 ID 在两个对象中具有相同长度时才匹配

从根本上说,第一种方法是有缺陷的。考虑三个条目:

A = { Name=¨N1¨, ID=¨ID1¨ }
B = { Name=¨N2¨, ID=¨ID1¨ }
C = { Name=¨N2¨, ID=¨ID2¨ }

你似乎想要:

A.Equals(B) - true
B.Equals(C) - true
A.Equals(C) - false

这违反了相等性规则(传递性)。

强烈建议您只使用两组 - 一组按 ID 比较值,另一组按名称比较值。然后编写一个方法,只在 两个 集合中都没有出现的条目时才添加一个条目。

关于c# - 如何正确实现 HashSet 的 IEqualityComparer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5792813/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com