2

我得到一个空引用异常,但不知道为什么(见代码)。

我有以下代码作为我正在制作的反序列化器的一部分。当我的类的反序列化实例缺少某些键时,以下代码将默认键/值添加到一组字典中。这样做的原因是,当客户部署我的插件的新版本时,即使他们没有所有密钥,他们的旧设置仍然会正确反序列化。

这是我的代码:

private Dictionary<string, T> AddMissingSettings<T>(Dictionary<string, T> settingsObject, bool forceDefaults, string[] settingsList)
{
    if (forceDefaults || settingsObject == null)
    {
        settingsObject = new Dictionary<string, T>();
    }
    foreach (string t in settingsList)
    {
        if (!settingsObject.ContainsKey(t))
        {
            settingsObject.Add(t, default(T));// Null Reference Exception Here
        }
    }
    return settingsObject;
}

这是我调用该方法的示例:

Dictionary<string, DateTime> Times = getlistoftimesettingsfromdata();
//Note: Not the real way Times gets set, but whatever
Times = AddMissingSettings<DateTime>(Times, forceDefaults, new string[] { "LastEmailUpdate", "IdealRegularReportTime", "LastRegularReport" });
//Also, pretty sure the "Times = " here is redundant, but let it pass

将 VPNd 编辑到工作中以发布我正在使用的实际代码。我可以确认它可以编译并运行。

    private void LoadDefaults(bool forceDefaults)
    {
        if (RegularReportDays == null || forceDefaults) { RegularReportDays = new List<DayOfWeek>(); }
        if (RegularReportSubscribers == null || forceDefaults) { RegularReportSubscribers = new List<string>(); }
        Times = AddMissingSettings<DateTime>(Times, forceDefaults, DateTime.MinValue, new string[] { "LastEmailUpdate", "IdealRegularReportTime", "LastRegularReport" });
        Toggles = AddMissingSettings<bool>(Toggles, forceDefaults, false, new string[] { "AutomaticUpdates", "AutomaticUpdatesAlerts", "SendRegularReports" });
    }

    private Dictionary<string, T> AddMissingSettings<T>(Dictionary<string, T> settingsObject, bool forceDefaults, T defaultValue, string[] settingsList)
    {
        if (forceDefaults || settingsObject == null)
        {
            settingsObject = new Dictionary<string, T>();
        }
        foreach (string t in settingsList)
        {
            if (!settingsObject.ContainsKey(t))
            {
                settingsObject.Add(t, defaultValue);
            }
        }
        return settingsObject;
    }
4

2 回答 2

2

好的,所以我周一回来时精神焕发,我明白问题出在哪里。问题正在发生 - 正如其他人已经嗅出的那样 - 更进一步。这个解决方案的关键在于我没有提到的地方,因为我认为它不相关(对不起)。

我试图运行以下堆栈

  • private Dictionary<string, T> AddMissingSettings<T>(Dictionary<string, T> settingsObject, bool forceDefaults, string[] settingsList)
  • private void LoadDefaults(bool forceDefaults)
  • public BookEasyImportServiceSettings(SerializationInfo info, StreamingContext cxt)

您可能会注意到我正在尝试更改对象的成员,同时它正在被反序列化。看来你不能这样做。所以我LoadMissingDefaults向我的界面添加了一个公共方法,并在BinaryFormatter.Deserialize(Stream)完成后调用它。

现在,我真的不喜欢给自己奖励答案(尽管同样,我不喜欢解决我的问题,也不喜欢分享我的解决方案——所以我有时会这样做)。如果有人可以就为什么会这样和/或更好的方法提交一个很好的答案,我会将获奖答案转给他们。

于 2012-10-08T05:45:04.600 回答
1

您不能null用作 中的键Dictionary。从您的代码settingsListstring[]并且string可以是null. 我建议您在将 null 添加到settingObject.

foreach (string t in settingsList) 
{ 
    if (t != null && !settingsObject.ContainsKey(t)) 
    { 
        settingsObject.Add(t, default(T));// Null Reference Exception Here 
    } 
} 
于 2012-10-05T09:47:02.987 回答