【问题标题】:use dictionary containskey comparer with different attributes [duplicate]使用具有不同属性的字典包含键比较器[重复]
【发布时间】:2018-06-22 20:53:32
【问题描述】:

我试图找到一种正确的方法来使用类属性在字典中查找键。

例如看下面的代码 - ContainsKey 是错误的,因为当键是 UserServiceData 时,没有实现此 ContainsKey(string) 签名。

我该如何解决这个问题?

class UserServiceData 
{
    string name;
    int someDate;
    int someData1;
}

class B
{
    public static Dictionary<UserServiceData, IClientKdcCallBack> users_list = new Dictionary<UserServiceData, IClientKdcCallBack>;

    void isUserExists(string userName)
    {
        m_users_list.ContainsKey(userName)
    }
}

【问题讨论】:

    标签: c# dictionary


    【解决方案1】:

    您也可以尝试编写自己的相等比较器。

    private class UserServiceDataEqualityComparer : IEqualityComparer<UserServiceData>
    {
        public bool Equals(UserServiceData x, UserServiceData y)
        {
            return x.name == y.name;
        }
    
        public int GetHashCode(UserServiceData obj)
        {
            return obj.name.GetHashCode();
        }
    }
    

    然后像这样声明你的字典..

    var list = new Dictionary<UserServiceData, IClientKdcCallBack>(new UserServiceDataEqualityComparer());
    

    然后你就可以这样做了

    list.ContainsKey(UserServiceDataObj)
    

    【讨论】:

    • 我试过这种方式,但是如果输入的不是键的类型而是键包含的一些属性,例如 list.ContainsKey(string) 怎么办?
    • @LIOR 参见 Equals 方法。你可以随意改变它
    • @LIOR Dictionary 不存在这样的重载。您要么需要编写自己的扩展方法,将字符串作为参数,并编写其他答案中建议的自定义逻辑,要么使用我的解决方案。这取决于你。
    【解决方案2】:

    假设“UserServiceData”类的“name”属性在 Dictionary 本身中是唯一的,您可以这样做:

    users_list.Any(x => x.Key.name == userName);
    

    如果存在两个具有相同用户名的 UserServiceData 实例,它仍然会返回 true,所以要小心。

    【讨论】:

      【解决方案3】:

      使用添加

      using System.Linq;
      

      然后

      public void isUserExists(string userName)
      {
         bool result = m_users_list.Keys.Any(x => x.name == userName);
      }
      

      注意UserServiceData 的所有字段都是私有的!要完成这项工作,您至少需要将其公开:

       class UserServiceData 
       {
          public string name;
          public int someDate;
          public int someData1;
       }
      

      所以工作代码是:

      class UserServiceData
      {
          public string Name   { get; set; }
          public int SomeDate  { get; set; }
          public int SomeData1 { get; set; }
      }
      
      class B
      {
          public static IDictionary<UserServiceData, IClientKdcCallBack> users_list = new Dictionary<UserServiceData, IClientKdcCallBack>();
      
          public bool isUserExists(string userName)
          {
              return users_list.Keys.Any(x => x.Name.Equals(userName));
          }
      }
      

      【讨论】:

      • 使用字典的目的是为了更快地访问项目(在O(1)时间)。但是您使用 (m_users_list.Keys.Any(x =&gt; x.name == userName);) 迭代整个 KeyValue 对(当然,如果找到一个项目,它可以在循环整个字典之前返回)。
      猜你喜欢
      • 1970-01-01
      • 2011-02-07
      • 2022-11-29
      • 1970-01-01
      • 2018-09-25
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多