除非我通过本地查看变量,否则SettingsPropertyValue.SerializedValue为null

时间:2011-11-16 18:04:51

标签: c# serialization application-settings

我正在ApplicationSettings内存储C#程序中使用的一些常用设置。大多数设置都是字符串,但其中一个是StringCollection

在某些代码中出现空异常,这些代码循环遍历Properties.Settings.Default的默认设置并将它们添加到字典中(准备作为参数发送),如下所示。

// Generate parameters
Dictionary<string, string> signalparams = new Dictionary<string, string>();

// Add parameters
foreach (SettingsProperty property in Properties.Settings.Default.Properties)
{
    SettingsPropertyValue value = new SettingsPropertyValue(property);

    if (value.Property.SerializeAs == SettingsSerializeAs.Xml)
    {
        // Here's where the error occurs
        signalparams.Add(value.Name, value.SerializedValue.ToString());
    }
    else if (value.Property.SerializeAs == SettingsSerializeAs.String)
    {
        signalparams.Add(value.Name, value.PropertyValue.ToString());
    }
}

字符串设置添加正常,但当它到达StringCollection时,它(正确)评估该属性具有SerializeAs == SettingsSerializeAs.Xml。但是,SerializedValue为空,因此ToString()会抛出异常。

奇怪的是,在运行调试器时,SerializedValue为空,直到我尝试在本地窗口中查看value变量的属性。此时,SerializedValue包含StringCollection的正确XML序列化格式,程序继续正常。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

问题可能源于SerializedValue是一个实现类似的属性:

public object SerializedValue
{
  get
  {
    if (this._ChangedSinceLastSerialized)
       return CalculateSerializedData();
    else
       return _cachedData;
   }
}

在我看来,在你的情况下,当你第一次访问SettingPropertyValue时,你会得到_cachedData,然后,通过调试器查看value,你会导致_ChangedSinceLastSerialized成为true {1}}导致下一次调用SerializedValue属性返回实际的序列化值。

接下来的问题是找出案例中_ChangedSinceLastSerialized设置为false的原因。 SettingsPropertyValue的逻辑说(你可以在类的PropertyValue属性中的Reflector中看到它)当用户访问设置时_ChangedSinceLastSerialized被设置为true(在大多数对象的情况下)例如,仅仅访问您的设置:MyAppSettings.Default.MySettingObject会将_ChangedSinceLastSerialized更改为true

如果您的代码与此类似,可能会发生什么:

object storingObject = MyAppSettings.Default.MySettingObject;
// Now I will use storingObject to access the setting.

一旦你做了类似的事情并继续使用storingObject而不是直接访问MyAppSettings,你就可以创建一种情况,当_ChangedSinceLastSerialized保持false时,对象会发生变化。< / p>

我希望这很有帮助。

答案 1 :(得分:0)

我实际上放弃了尝试使用SettingsPropertyValue并决定手动将对象序列化为XML。我只是使用SettingsProperty.Name作为密钥来检索Properties.Settings.Default中存储的设置的值,因为它是一个类似字典的对象。它解决了这个问题,但当然根本原因仍然未知。修改后的代码看起来像这样:

// Generate parameters
Dictionary<string, string> signalparams = new Dictionary<string, string>();

// Add parameters
foreach (SettingsProperty property in Properties.Settings.Default.Properties)
{
    if (property.SerializeAs == SettingsSerializeAs.String)
    {
        signalparams.Add(property.Name, Properties.Settings.Default[property.Name].ToString());
    }
    else if (property.SerializeAs == SettingsSerializeAs.Xml)
    {
        // Serialize collection into XML manually
        XmlSerializer serializer = new XmlSerializer(Properties.Settings.Default[property.Name].GetType());

        StringBuilder sb = new StringBuilder();
        XmlWriter writer = XmlWriter.Create(sb);

        serializer.Serialize(writer, Properties.Settings.Default[property.Name]);
        writer.Close();

        signalparams.Add(property.Name, sb.ToString());
    }
}
相关问题