【问题标题】:How to check if a key exists when using an entity as a key in c # dictionary? [duplicate]c#字典中使用实体作为键时如何检查键是否存在? [复制]
【发布时间】:2021-09-30 09:22:47
【问题描述】:

我有一个实体列表,我想检查其中有多少是某些属性所共有的。 所以我用了字典

List<Letter> allPsukim = await _context.Letter.Where(a => a.OrderId == Order.Id)
                                              .ToListAsync();
foreach (var item in allPsukim)
{
    Psukim newPasuk = new Psukim()
    {
        Book = item.Book,
        Pasuk = item.Pasuk,
        Perek = item.Perek
    };

    if (showPsukim.ContainsKey(newPasuk))
    {
        List<int> newList = showPsukim[newPasuk];
        newList.Add(item.Position);
        showPsukim[newPasuk] = newList;
    }
    else
    {
        List<int> newList = new List<int>() { item.Position };
        showPsukim.Add(newPasuk, newList);
    }
}

问题是showPsukim.ContainsKey(newPasuk) 总是显示不存在密钥。

在哪里可以使用实体作为键并检查它是否存在?

【问题讨论】:

  • 如果你总是 "new Psukim ()" ,那将是一个新键
  • 想一想,实际的“作为字典键的自定义对象”与此 Q 不重复。这个问题将不胜感激,因为拥有“好”键比较器可能不是最好的解决方案。

标签: c#


【解决方案1】:

目前您正在比较对象引用而不是值。比较值的一种方法是使用字符串作为键,该键组合了比较相等性所需的序列化属性。例如,您可以键入 Book、Perek 和 Passuk 属性的串联:

string key = item.Book + "-" + item.Perek + "-" + item.Passuk;
dic.Add(key,item);

然后查询key:

if(dic.ContainsKey(key)){...}

当然,您可以向 Letter 类添加一个 Serialize() 方法,该方法将返回 Object 的序列化表示并将其用作字典的键。

或者,您可以覆盖 GetHashCode() 方法。

【讨论】:

    【解决方案2】:

    如果是引用类型,当你新的时候它会是一个新的键。 所以尝试更改为结构,当您的字段完全相同时,它的键是相同的。

    public class Psukim 
    {
        //...
    }
    

    改成这样:

    public struct Psukim 
    {
        //...
    }
    

    或者 Override GetHashCode() ,你可以选择几个字段来组合一个新的键。

    public class Psukim 
        {
            //...
        
            public override int GetHashCode()
            {
                // set what you want field to combine a key.
                return System.HashCode.Combine(Book, Perek);
            }
    
            public override bool Equals(object obj)
            {
                Key other = obj as key;
                return other != null && other.Book == this.Book && other.Perek == this.Perek;
            }
        }
    

    【讨论】:

    • 如果 OP 只想比较几个属性怎么办?为了平等而将类更改为结构是一个非常糟糕的主意。
    • 我猜这个类只是为了比较,一个临时类或结构,如果想比较几个成员,我认为覆盖 GetHashCode() 更好。
    猜你喜欢
    • 2021-11-02
    • 2014-08-17
    • 2012-03-27
    • 2016-03-20
    • 2012-06-15
    • 2016-09-19
    • 1970-01-01
    • 2017-06-23
    • 2011-02-19
    相关资源
    最近更新 更多