C# 这本词典怎么样<;TKey,TValue>;可能有例外吗?

C# 这本词典怎么样<;TKey,TValue>;可能有例外吗?,c#,.net,exception,dictionary,C#,.net,Exception,Dictionary,给定以下堆栈跟踪: 消息:值不能为null。参数名称:key 资料来源:mscorlib TARGETSITE:Void ThrowArgumentNullException(系统异常参数) 堆栈跟踪: 在System.ThrowHelper.ThrowArgumentNullException处(参数异常) 位于System.Collections.Generic.Dictionary的2.FindEntry(TKey) 位于System.Collections.Generic.Diction

给定以下堆栈跟踪:

消息:值不能为null。参数名称:key
资料来源:mscorlib
TARGETSITE:Void ThrowArgumentNullException(系统异常参数)
堆栈跟踪:
在System.ThrowHelper.ThrowArgumentNullException处(参数异常)
位于System.Collections.Generic.Dictionary的2.FindEntry(TKey)
位于System.Collections.Generic.Dictionary的2.get_项(TKey)
在D:\Development\MAF\Agent\MyCompany.MAF.Agent\ServiceContracts\ConvertUtils.Convert(字典的2-from)中的MyCompany.MAF.Agent\ServiceContracts\ConvertUtils.cs:第11行
我的结论是,不知何故,下面的代码块从输入字典的Keys集合中检索到了null。但是,输入字典是
字典
的一个实例,
字典
的实现使得这种情况不可能发生。添加具有空键的项时,将引发异常

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();
}
内部静态KeyValuePair[]转换(IDictionary from)
{
List ret=新列表();
foreach(从.Keys输入字符串)
ret.Add(新的KeyValuePair(key,from[key]));
返回返回返回到阵列();
}

看起来更像是您的
IDictionary
参数有一个带有
Key
参数的项,该参数为null


IDictionary
的参数检查可能会在框架内部的某个地方进行

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

我经常遇到这个问题,因为我犯了允许多个线程访问同一个字典的错误。请确保情况并非如此,因为
Dictionary
不是线程安全的


(顺便说一句,您的方法可以大大简化。
字典
已经是一个
IEnumerable
。您应该可以在一个上执行
到阵列

不确定空值,但为什么不使用:

internal static KeyValuePair<string, string>[] Convert(IDictionary<string, string> from)
{
    return from.ToArray();
}
内部静态KeyValuePair[]转换(IDictionary from)
{
从.ToArray()返回;
}
编辑:就空值而言。您是否有多个线程访问此IDictionary?如果您不是线程安全的,则可能会发生损坏。请参阅本文以了解

Queue<T>
队列

类.< /P> < P>是否有可能是另一个线程正在影响DICORACION被传递到转换?

线程可能是原因,但在我们的情况下它是一个红色鲱鱼。如果您有一个强的“发布版本< /强>,其中一个函数被内嵌,您也可以看到这个问题。请考虑这个RePro:

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);
    }
}
但是,它在发布版本中给出了这个堆栈跟踪:

at System.Collections.Generic.Dictionary`2.FindEntry(TKey)
在System.Collections.Generic.Dictionary`2.TryGetValue(TKey、TValue和value)
位于MyApp.Program.Main(字符串[]args)
您可能会认为最后一个堆栈跟踪必须是
things.TryGetValue
导致异常,而实际上是
某些似乎未更新的函数
内联在
Main


所以如果你登陆这里,请考虑如果你有类似的问题。(我意识到这可能不是OP问题的直截了当的答案,但是想分享它,因为它可能对未来的访问者有帮助。)

字典不能用空值项填充key@goofballogic,为true,但您只能在运行时发现您的键字符串是否为null,然后获取异常…否,如果有人试图使用null键填充字典,则字典将引发异常。显示的异常是检索值,而不是添加/插入值。@goofballlogic th参数类型是IDictionary而不是Dictionary,前者可以有一个空键(接口中没有禁止该项的内容)。您知道正在传递的参数实际上是一个字典吗?是的,这仅从正在传递字典的整个代码库中的一个点引用。我已尝试创建线程的竞争条件,但失败。即使存在线程问题,
key
也不可能初始化为null fr关于ToArray方法的Keys collectionGood point-这并不能解释异常,但我怀疑它会阻止它的发生。不,你不能有空键,但是
字典使用的内部方法在进入某些状态时仍然会抛出此异常。我见过很多这种情况,尤其是在使用ASP.NET应用程序中未受保护的静态字典。@goofballlogic:这是人们所期望的,但请检查我答案中的链接,以了解是否存在导致Queue.Dequeue()的竞争条件当队列从不包含null时返回null项。如果这些非线程安全对象上没有线程安全性,行为将变得非常意外。+1,如果不使用锁对其进行保护,线程可能会破坏内部结构并在存储桶中创建null项。当n元素数量的增长足以需要更多的存储桶。这一点很好-这并不能解释异常,但我怀疑它会阻止异常的发生。@goofballlogic:请参阅我的更新。如果IDictionary已损坏,则简化方法可能不是解决方案。您可能需要在IDictionary周围实现一些锁定。因为没有真正回答您的问题(我最好的猜测是它与线程相关),但是您的循环是多余的。ToArray()将产生相同的结果传入的字典不是字典