查找字典中的值通过key's属性

本文关键字:key 通过 属性 class2 字典 class1 查找 | 更新日期: 2023-09-27 18:11:04

我有一本字典:

private Dictionary<MetaInfoValueGroupTag, List<object>> checkedMetainfoValues;

可以看到Key类是MetaInfoValueGroupTag:

private class MetaInfoValueGroupTag
{
    private string metainfo;
    //...
    public string MetaInfo
    {
        get { return metainfo; }
        set { metainfo = value; }
    }
    //...
}

我需要使用字符串对象获得Value。因此,我需要根据string检查一个键是否存在。

string值表示MetaInfoValueGroupTag字典键对象的Metainfo property string内容。

List<object> values = null;
this.checkedMetainfoValues.TryGetValue("metainfo_sample", out values);

我不想写:

List<object> values = null;
this.checkedMetainfoValues.TryGetValue(new MetaInfoValueGroupTag("metainfo_sample"), 
                                       out values);

我想避免创建一个新的转储key对象来获取它的值。

我想它必须有可能实现IComparer或使用AnonymousComparer。

查找字典中的值<class1, class2>通过key's属性

Dictionary不是这样工作的。它为元素的键构建散列表,并使用它进行快速搜索。

它使用IEqualityComparer<T>来判断键是否相等,但是你不能用它来与MetaInfoValueGroupTag以外的其他类型进行比较。

但是,您可以使用LINQ扩展方法并使用Dictionary为IEnumerable的事实。这意味着您可以一个元素一个元素地枚举它,并找到您需要的内容。在这里,您可以使用自定义比较器或仅使用lambda谓词。

为了使用扩展方法,您需要为它们添加using:

using System.Linq;

之后,您可以使用以下方法在您的字典中查找单个元素:

var searchedElement = checkedMetainfoValues.SingleOrDefault(x=>x.Key.MetaInfo == "metainfo_sample");

但是请记住,它将抵消快速获取元素的任何字典好处。它只是一个一个地检查所有元素,直到所提供的条件满足或到达字典的末尾。

最后,最好修改你的字典,使用string作为关键字,或者,如果不可能,只是创建MetaInfoValueGroupTag对象,并使用它作为关键字。

但是要注意,它依赖于MetaInfoValueGroupTag的哈希算法。有可能哈希值不仅取决于MetaInfo值,因此new MetaInfoValueGroupTag("metainfo_sample")可能不适合您的搜索。

阅读更多:https://msdn.microsoft.com/en-us/library/xfhwa508(v=VS.110).aspx

您可以像这样获得整个键/值对:

var entry = checkedMetainfoValues.Where(x => x1.Key.MetaInfo == "metainfo_sample").Single();

我猜字符串值是唯一的,否则你的访问字符串将不起作用。我建议将键改为string。

private Dictionary<string, List<object>> checkedMetainfoValues;
// access by meta info:
MetaInfoValueGroupTag metaInfoGroupTag;
var value = checkedMetaInfoValues[metaInfoGroupTag.MetaInfo]
// access by string:
string metaInfo;
var value = checkedMetaInfoValues[metaInfo]

如果你特别需要这种语法:

List<object> values = null;
this.checkedMetainfoValues.TryGetValue("metainfo_sample", out values);

您可以创建自己的字典,继承自普通字典,如下所示:

private class MyStrangeDictionary : Dictionary<MetaInfoValueGroupTag, List<object>>
{
    public MyStrangeDictionary() : base(MetaInfoValueGroupTag.MetainfoComparer)
    {
    }
    public List<object> this[string key]
    {
        get
        {
            return this[new MetaInfoValueGroupTag {MetaInfo = key}];
        }
        //set
        //{
        //    Add(new MetaInfoValueGroupTag { MetaInfo = key }, value);
        //} 
    }
    public bool TryGetValue(string key, out List<object> value)
    {
        if (ContainsKey(new MetaInfoValueGroupTag {MetaInfo = key}))
        {
            value = this[key];
            return true;
        }
        value = default(List<object>);
        return false;
    }
}

用法如下:

_checkedMetainfoValues = new MyStrangeDictionary();
_checkedMetainfoValues.Add(new MetaInfoValueGroupTag { MetaInfo = "f"}, new List<object> { "first"});
_checkedMetainfoValues.Add(new MetaInfoValueGroupTag { MetaInfo = "s"}, new List<object> { "second", "2"});
var test = _checkedMetainfoValues["f"];
foreach (var t in test)
{
    Console.WriteLine(t);
}
List<object> test1;
_checkedMetainfoValues.TryGetValue("s", out test1);
foreach (var t in test1)
{
    Console.WriteLine(t);
}

编辑:

为了完整起见,这里是你的类和比较器:

private class MetaInfoValueGroupTag
{
    private sealed class MetainfoEqualityComparer : IEqualityComparer<MetaInfoValueGroupTag>
    {
        public bool Equals(MetaInfoValueGroupTag x, MetaInfoValueGroupTag y)
        {
            if (ReferenceEquals(x, y)) return true;
            if (ReferenceEquals(x, null)) return false;
            if (ReferenceEquals(y, null)) return false;
            if (x.GetType() != y.GetType()) return false;
            return string.Equals(x.metainfo, y.metainfo);
        }
        public int GetHashCode(MetaInfoValueGroupTag obj)
        {
            return (obj.metainfo != null ? obj.metainfo.GetHashCode() : 0);
        }
    }
    private static readonly IEqualityComparer<MetaInfoValueGroupTag> MetainfoComparerInstance = new MetainfoEqualityComparer();
    public static IEqualityComparer<MetaInfoValueGroupTag> MetainfoComparer
    {
        get { return MetainfoComparerInstance; }
    }
    private string metainfo;
    //...
    public string MetaInfo
    {
        get { return metainfo; }
        set { metainfo = value; }
    }
    //...
}