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

是否可以获取包含的KeyValuePair a 直接从字典里取?
或者我是否需要创建一个新的 KeyValuePair: new KeyValuePair<A, B>(a, dict[a])?

有帮助吗?

解决方案

你需要创建一个新的 KeyValuePair 1 - 但请记住KVP是一种值类型(结构),所以它不像你介绍的那样这样做会带来新的低效率。任何返回KVP的方法都会创建一个副本 - 你只是直接创建实例。

如果您愿意,可以随时向 IDictionary&lt; TKey,TValue&gt; 添加扩展方法:

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

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


1 我知道你可以迭代字典条目并找到相应的条目,但我没有理由为什么你曾经想要这样做一个非常好的索引器,它是O(1)而不是O(N)。

其他提示

Dictionary&lt; TKey,TValue&gt; 实现 IEnumerable&lt; KeyValuePair&lt; TKey,TValue&gt;&gt; 时,你可以使用linq:

var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);

我们无法到达 "IPHone" 这边走:

var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
               {
                   { "IPHone", "TCP/IP honing tools" }
               };

Console.WriteLine(dict["iPhone"]); // "TCP/IP honing tools"
Console.WriteLine( ??? ); // "IPHone"

当前 API 似乎没有 O(1) 解决方案,但循环遍历所有条目是可行的:

var keyValue = dict.First(p => dict.Comparer.Equals(p.Key, "iPhone"));

Console.WriteLine(keyValue.Key); // "IPHone"
Console.WriteLine(keyValue.Value); // "TCP/IP honing tools"

或者作为懒人的扩展:

[Pure]
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
    var comparer = dictionary.Comparer;
    return dictionary.FirstOrDefault(p => comparer.Equals(p.Key, key));
}

对我来说 myDict.AsEnumerable 做到了......

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top