通过键的属性在Dictionary <class1,class2 =“”>中查找值

时间:2015-09-04 07:00:47

标签: c# dictionary

我有一个词典:

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值表示Metainfo property string字典密钥对象的MetaInfoValueGroupTag内容。

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

4 个答案:

答案 0 :(得分:0)

Dictionary不会那样工作。它为其元素的键构建哈希表,并将其用于快速搜索。

它使用IEqualityComparer<T>来确定密钥是否相等,但您不能使用它来将其与您MetaInfoValueGroupTag以外的不同类型进行比较。

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我猜字符串值是唯一的,否则你的字符串访问将无效。我建议将密钥更改为字符串。

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]

答案 3 :(得分:0)

如果你想要特定的语法:

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; }
    }
    //...
}