直接从字典<>获取KeyValuePair <>

use*_*783 32 .net c# generics collections dictionary

我有System.Collections.Generic.Dictionary<A, B> dictA和B是类和一个实例A a(其中dict.ContainsKey(a)是真的).

是否有可能a直接从Dictionary中获取KeyValuePair ?
或者,我需要创建一个新的KeyValuePair: new KeyValuePair<A, B>(a, dict[a])

Jon*_*eet 39

你需要创建一个新的KeyValuePair1 - 但请记住,KVP无论如何都是一个值类型(结构),所以这并不像你通过这样做引入新的低效率.任何返回KVP的方法都会创建一个副本 - 你只是直接创建实例.

如果需要,您可以随时添加扩展方法IDictionary<TKey, TValue>:

public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>
    (this IDictionary<TKey, TValue> dictionary,
     TKey key)
{
    return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
Run Code Online (Sandbox Code Playgroud)

正如评论中所指出的,存储在字典中的密钥完全有可能与提供的密钥不同,只是在语义上相等 - 通过某些语义可以由一个IEqualityComparer(例如,不区分大小写的字典)定制..)在这种情况下,上面的代码不会返回字典中的实际条目,而是返回您提供的用于查找的键的条目.不幸的是,没有找到原始密钥的有效方法 - 你必须迭代字典:(


1我知道你可以迭代字典条目并找到相应的条目,但是当你有一个非常好的索引器是O(1)时,我看不出你为什么要这么做的理由而不是O(N).

  • 不幸的是,上述仅在密钥参数和存储在字典中的密钥在语义上相等时才有效.如果有一个`Dictionary <string,string>```dic`由`StringComparer.InvariantCultureIgnoreCase`构成,它包含{"Jon","Skeet"},那么`dic.GetEntry("JON")`将返回{" JON", "斯基特"}.我知道使字典返回查找键的唯一方法是让键成为值的一部分.看起来很傻,但我知道别无选择. (6认同)
  • 我的想法是:"我似乎无法在字典中获得对实际KeyValuePair对象的引用.我想知道为什么不呢?".KeyValuePair是一种值类型,清楚地回答了这一点.谢谢乔恩 (2认同)
  • @eglasius:我真的希望Sun和Microsoft已经认识到,在许多情况下,拥有存储在字典或集合中的确切密钥是有用的.缺乏这样的能力对Java的'WeakHashMap`特别有害[我可以看到'WeakIdentityHashMap`的更强用例,或者'WeakReflexiveSet` [将键映射到自己]比用于非基于身份的`WeakHashSet`那样不能轻易读回存储的键值. (2认同)

Oli*_*ppi 18

作为Dictionary<TKey, TValue>工具IEnumerable<KeyValuePair<TKey, TValue>>,您可以使用linq:

var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
Run Code Online (Sandbox Code Playgroud)

  • 是的,你*可以*做到这一点......但与获取密钥相比,它的效率低得惊人.(它还假设==已经为密钥类型重载,并且字典正在使用该比较.)为什么你想要这样做而不是直接创建一个新的KVP? (9认同)
  • 这是不对的!!!非常糟糕的代码避免它!考虑一个9999999项目的字典,你可以直接去你的项目并创建这个项目,或者经历很多项目并得到它......想一想.. (4认同)