C# 检查字典是否包含任何具有特定属性的键对象

C# 检查字典是否包含任何具有特定属性的键对象,c#,dictionary,C#,Dictionary,我想知道这是否可以用C完成。我有一个字典(),其中键和值是: public Device { public string Id; } public User { public string Name; } 我想知道我的字典是否包含用户键,该键的名称属性等于“John”。想象一下有这样的事情: myDictionary.ContainsKey(key => key.Name == "John"); 这可能吗?字典是一个“IEnumerable”,这意味着您可以: my

我想知道这是否可以用C完成。我有一个
字典()
,其中键和值是:

public Device {
    public string Id; 
}

public User {
    public string Name;
}
我想知道我的字典是否包含
用户
键,该键的
名称
属性等于
“John”
。想象一下有这样的事情:

myDictionary.ContainsKey(key => key.Name == "John");
这可能吗?

字典是一个“IEnumerable”
,这意味着您可以:

myDictionary.Any(kvp => kvp.Key.Name == "John");
但那将是一个O(n)操作

如果您关心hashmap性能(因此使用dictionary?),您可以覆盖
GetHashCode()
User
类的等式,这样
newuser{Name=“John”}.Equals(newuser{Name=“John”})
将为true,允许:

myDictionary.ContainsKey(new User { Name = "John" });
这是O(1)

,有两个修改(即选择一个适合您的需要),您可以这样做:

  • 您可以覆盖
    User
    上的
    GetHashCode
    Equals
    ,以使两个不同的
    User
    实例相等(如果它们具有相同的
    名称
    值)
  • 您可以向字典提供一个
    IEqualityComparer
    实例,该实例与第1点具有相同的效果,只是在
    User
  • 选项1:覆盖GetHashCode和Equals 使用此
    用户
    实现:

    public class User
    {
        public string Name;
    
        public override int GetHashCode() => Name?.GetHashCode() ?? 0;
        public override bool Equals(object other) => (other as User)?.Name == Name;
    }
    
    您可以通过以下方式查询此类用户:

    myDictionary.ContainsKey(new User { Name = "John" });
    
    ()

    选项2:实施IEqualityComparer 在本课程中:

    public class UserEqualityComparer : IEqualityComparer<User>
    {
        public bool Equals(User x, User y) => x?.Name == y?.Name;
        public int GetHashCode(User obj) => obj?.Name?.GetHashCode() ?? 0;
    }
    
    然后您可以再次这样查询:

    var myDictionary = new Dictionary<User, Device>(new UserEqualityComparer());
    
    myDictionary.ContainsKey(new User { Name = "John" });
    
    ()



    如果这两个都不是选项,那么您可以使用线性搜索,它的性能就像是
    KeyValuePair
    的集合一样,这正是它所要的,并且可能没有您想要的性能特征。

    从技术上讲,
    bool contains=myDictionary.Keys.Any(key=>key.Name==“John”)
    它将具有与列表相似(但稍差)的性能特征,因此它是一个字典这一事实不会有任何帮助(“稍差”只是因为枚举字典时会有很小的开销,因为它围绕每个元素构造一个
    KeyValuePair
    ,并且必须遍历bucket,而不是线性列表). 简而言之,没有快速的方法可以获得它,如果您需要它,您可能需要以某种方式重新组织数据结构以获得该对象的查找。如果您在
    用户
    上实现了
    GetHashCode
    Equals
    ,您可能只需要用正确的名称构造一个新的
    用户
    ,并对其进行查询。如果没有,您别无选择,只能找到指向具有该名称的
    用户的确切引用。换句话说,如果两个不同的
    User
    实例具有相同的
    名称
    值,那么就.Equals和.GetHashCode而言,您可以这样做:
    myDictionary.ContainsKey(新用户{Name=“John”})同意@LasseVågsætherKarlsen。如果你不得不这么做,也许字典不是你要找的容器。