这个Dictionary <tkey,tvalue =“”>例外怎么可能?</tkey,>

时间:2010-02-17 18:44:13

标签: c# .net exception dictionary

给出以下堆栈跟踪:

MESSAGE: Value cannot be null.Parameter name: key  
SOURCE: mscorlib  
TARGETSITE: Void ThrowArgumentNullException(System.ExceptionArgument)  
STACKTRACE:  
   at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)  
   at System.Collections.Generic.Dictionary'2.FindEntry(TKey key)  
   at System.Collections.Generic.Dictionary'2.get_Item(TKey key)  
   at MyCompany.MAF.Agent.ServiceContracts.ConvertUtils.Convert(Dictionary'2 from) in D:\Development\MAF\Agent\MyCompany.MAF.Agent\ServiceContracts\ConvertUtils.cs:line 11

我得出结论,以下代码块以某种方式从输入Dictionary的Keys集合中检索了一个null。但是,输入字典是Dictionary<string, string>的实例。 Dictionary<string, string>的实现使得该条件无法实现。添加带有空键的项目后,将抛出异常。

internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from)
{
    List<KeyValuePair<string, string>> ret = new List<KeyValuePair<string, string>>();
    foreach (string key in from.Keys)
        ret.Add(new KeyValuePair<string, string>(key, from[key]));
    return ret.ToArray();
}

6 个答案:

答案 0 :(得分:12)

我经常遇到这个问题,因为我错误地允许多个线程访问同一个字典。确保不是这种情况,因为Dictionary不是线程安全的。

(顺便提一下,您的方法可以大大简化。Dictionary<K,V>已经是IEnumerable<KeyValuePair<K,V>>。您应该只能在ToArray上进行操作。

答案 1 :(得分:3)

看起来更像是IDictionary参数的参数为​​Key的项目为空。

IDictionary的参数检查可能会在框架内部的某处发生。

答案 2 :(得分:2)

如果字典键为null,则会发生此异常。由于内置的​​Dictionary类不允许使用此类密钥,因此您可能正在使用自己的IDictionary兼容类,该类允许null

答案 3 :(得分:2)

不确定null,但为什么不使用:

internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from)
{
    return from.ToArray();
}

编辑:就空值而言。你有多个线程访问这个IDictionary?如果你不是线程安全的话,腐败是可能的。有关

中的损坏示例,请参阅此文章
Queue<T>

类。 How can I modify a queue collection in a loop?

答案 4 :(得分:2)

线程可能是原因,但在我们的案例中它是一个红色的鲱鱼。如果你有一个内联函数的发布版本,你也可以似乎来解决这个问题。考虑一下这个重复:

class Program
{
    static string someKey = null;

    static void Main(string[] args)
    {
        try
        {
            object thing;

            if (SomeSeeminglyUnrelatedFunction(someKey, out thing)) Console.WriteLine("Found");

            things.TryGetValue(someKey, out thing);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace.ToString());
            throw;
        }

        Console.ReadKey();
    }

    private static Dictionary<string, object> stuff = new Dictionary<string, object>();
    private static Dictionary<string, object> things = new Dictionary<string, object>();

    private static bool SomeSeeminglyUnrelatedFunction(string key, out object item)
    {
        return stuff.TryGetValue(key, out item);
    }
}

在我的机器上,这提供了以下 Debug build 堆栈跟踪:

at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at MyApp.Program.SomeSeeminglyUnrelatedFunction(String key, Object& item)
at MyApp.Program.Main(String[] args)

但是,它在发布版本中提供堆栈跟踪:

at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at MyApp.Program.Main(String[] args)

你很想用最后一个堆栈跟踪认为它 things.TryGetValue导致异常,而实际上它是SomeSeeminglyUnrelatedFunction函数在Main内联。

所以如果你降落在这里,请考虑你是否有类似的问题。 (我意识到这可能不是OP问题的直接答案,但是希望分享,因为它可能有助于未来的访问者。)

答案 5 :(得分:1)

是否可能是另一个线程正在影响传递给Convert的dirctionary?