查找字典中的值通过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。
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; }
}
//...
}