C# SettingsPropertyValue.SerializedValue为null,除非我通过局部变量查看变量
我将C程序中使用的一些常用设置存储在C# SettingsPropertyValue.SerializedValue为null,除非我通过局部变量查看变量,c#,serialization,application-settings,C#,Serialization,Application Settings,我将C程序中使用的一些常用设置存储在应用程序设置中。大多数设置都是字符串,但其中一个是StringCollection 某些代码中出现空异常,该代码在Properties.settings.default中循环默认设置,并将它们添加到字典中(准备作为参数发送),如下所示 // Generate parameters Dictionary<string, string> signalparams = new Dictionary<string, string>(); //
应用程序设置
中。大多数设置都是字符串,但其中一个是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());
}
}
//生成参数
Dictionary signalparams=新字典();
//添加参数
foreach(Properties.Settings.Default.Properties中的SettingsProperty属性)
{
SettingsPropertyValue值=新的SettingsPropertyValue(属性);
if(value.Property.SerializeAs==SettingsSerializeAs.Xml)
{
//这里是错误发生的地方
添加(value.Name,value.SerializedValue.ToString());
}
else if(value.Property.SerializeAs==SettingsSerializeAs.String)
{
添加(value.Name、value.PropertyValue.ToString());
}
}
字符串设置添加得很好,但是当它到达StringCollection
时,它(正确地)评估属性是否具有SerializeAs==SettingsSerializeAs.Xml
。但是,SerializedValue
为null,因此ToString()
引发异常
奇怪的是,在运行调试器时,SerializedValue
为空,直到我尝试在本地窗口中查看value
变量的属性。此时,SerializedValue
包含StringCollection
的正确XML序列化格式,并且程序继续正常运行
为什么会发生这种情况?问题可能源于这样一个事实,即
SerializedValue
是一个实现如下内容的属性:
public object SerializedValue
{
get
{
if (this._ChangedSinceLastSerialized)
return CalculateSerializedData();
else
return _cachedData;
}
}
在我看来,在你的情况下,当你第一次访问SettingPropertyValue时,你得到了缓存数据,然后,通过调试器查看值
,您将使\u ChangedSinceLastSerialized
变为true
,这将导致对SerializedValue
属性的下一次调用返回实际的序列化值
下一个问题是找出为什么在您的案例中,\u changedsincelasterialized
设置为false
。SettingsPropertyValue
的逻辑表示(您可以在类的PropertyValue
属性中的Reflector中看到)\u changedsInclastSerialized
在用户访问设置时设置为true(对于大多数对象类型),因此,例如,仅像这样访问您的设置:MyAppSettings.Default.MySettingObject将更改\u将从上次序列化的更改为true
如果您的代码与此类似,会发生什么情况:
object storingObject = MyAppSettings.Default.MySettingObject;
// Now I will use storingObject to access the setting.
一旦您执行类似操作并继续使用storingObject
而不是直接访问MyAppSettings
,您就可以创建这样一种情况,即对象在\u ChangedSinceLastSerialized
保持false
的同时发生更改
我希望这会有所帮助。我实际上放弃了使用设置属性值的尝试,决定手动将对象序列化为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());
}
}
//生成参数
Dictionary signalparams=新字典();
//添加参数
foreach(Properties.Settings.Default.Properties中的SettingsProperty属性)
{
if(property.SerializeAs==SettingsSerializeAs.String)
{
添加(property.Name,Properties.Settings.Default[property.Name].ToString());
}
else if(property.SerializeAs==SettingsSerializeAs.Xml)
{
//手动将集合序列化为XML
XmlSerializer serializer=新的XmlSerializer(Properties.Settings.Default[property.Name].GetType());
StringBuilder sb=新的StringBuilder();
XmlWriter=XmlWriter.Create(sb);
serializer.Serialize(writer、Properties.Settings.Default[property.Name]);
writer.Close();
signalparams.Add(property.Name,sb.ToString());
}
}
感谢您的富有洞察力的回答。就目前而言,我并没有像您所展示的那样从设置中检索对象,我只是尝试检索序列化的值,而不需要事先修改设置。可能是\u ChangedSinceLastSerialized
默认为false
,即使对象从未序列化。尽管如此,我还是通过手动序列化对象来解决这个问题。