0

我正要开始编写一个新的应用程序,我想弄清楚我是如何存储设置的。我几乎考虑过编写自己的设置系统,但后来决定我应该真正全面测试 .NET 提供的构建应用程序设置。所以我阅读了它并创建了一些测试代码。一切顺利,我想要的主要是一种重置值的方法,它可以轻松完成,但我想这样做而不自动将重置保存到设置文件中。

因此,我创建了以下代码,循环遍历设置类的每个属性,并使用默认值来更新当前值。

        foreach (SettingsProperty sp in Settings.Default.Properties)
        {
            PropertyInfo propertyInfo = Settings.Default.GetType().GetProperty(sp.Name);

            if (propertyInfo.CanWrite)
            {
                // Either convert from a string or de-serialize from XML
                object value;
                switch (sp.SerializeAs)
                {
                    case SettingsSerializeAs.String:
                        TypeConverter converter = TypeDescriptor.GetConverter(sp.PropertyType);
                        value = converter.ConvertFromInvariantString(sp.DefaultValue.ToString());
                        break;
                    case SettingsSerializeAs.Xml:
                        XmlSerializer serializer = new XmlSerializer(sp.PropertyType);
                        StringReader reader = new StringReader(sp.DefaultValue.ToString());
                        value = serializer.Deserialize(reader);
                        break;
                    default:
                        throw new FormatException(
                            string.Format(
                                Resources.ExceptionResetNoSaveSerializeAsInvalid,
                                sp.SerializeAs));
                }

                propertyInfo.SetValue(Settings.Default, value, null);
            }
        }

我开始时没有switch并且只有从字符串转换的代码。我的第一次尝试使用了这个:converter.ConvertFromString. 这适用于纯文本甚至 GUID 值,但日期失败。
(我添加的 XML 部分使序列化内容也能正常工作,但这不是这个问题的重点)

原版converter.ConvertFromString在日期上失败了。在我的测试中,我使用的是 '31/08/2012 11:25'。我一直在查看 Settings.Designer.cs 文件以查看它存储默认值的位置和方式,并注意到它是如何存储上述日期的默认值的:

    [global::System.Configuration.DefaultSettingValueAttribute("08/31/2012 11:25:15")]

我一直在网上搜索,但找不到任何参考资料来解释为什么在 Visual Studio 2010 设计器中输入 dd/mm/yyyy 格式会导致在自动生成的代码中使用 mm/dd/yyyy 格式。

正如您在上面的示例中看到的那样,我发现我可以使用converter.ConvertFromInvariantString并且日期错误确实消失了,但我仍然想知道是否有任何文档来解释差异。有没有其他人遇到过这个?

4

1 回答 1

0

是和不是。内部使用不变的文化。虽然这是一种特定的文化,但它显然不是一种真正的文化。

在内部,它使用和 之类的方法TypeConverter.ConvertToInvariantStringTypeConverter.ConvertFromInvariantString字符串中获取值。这就是字符串中的 mm/dd/yyy 的原因。当您在 UI 中输入日期/时间时,它会知道当地文化是什么,并以适合该文化的任何格式接受它。然后它在存储时“转换”为不变量。它这样做是因为它在读取值时不知道将设置什么文化。它默认为不变,因为这是一种特定且一致的文化。

就 而言DateTime,这既不是 UTC 也不是本地日期/时间。这允许您存储 UTC 或本地日期/时间值,您需要“转换”为DateTime对象,并将特定的 Kind 属性设置为您需要的任何值。建议您以 UTC 格式存储日期/时间值...

于 2012-08-11T20:19:36.513 回答