【问题标题】:Getting user settings collection types' default values in Visual Studio .NET在 Visual Studio .NET 中获取用户设置集合类型的默认值
【发布时间】:2017-07-08 05:05:34
【问题描述】:

我希望能够轻松地将单个用户设置重置为其默认值。 我写了一个这样的扩展:

public static void sReset(this Properties.Settings set, string key = "")
{
    if (key == "")
    {
        set.Reset();
        return;
    }
    Console.WriteLine("Reset '" + key + "' to: " + set.Properties[key].DefaultValue);
    set.PropertyValues[key].PropertyValue = set.PropertyValues[key].Property.DefaultValue;
}

这适用于原始类型。 但现在我想将它应用于 stringCollection,但它失败了:

发生了“System.InvalidCastException”类型的未处理异常 在 myApp.exe 中

附加信息:无法转换类型为“System.String”的对象 输入“System.Collections.Specialized.StringCollection”。

这是因为这些集合类型默认值(Stored serialized as XML)作为字符串返回: set.Properties[key].DefaultValue.GetType() 返回System.String

我可以在设置设计器中看到,通常它只是将值转换为 StringCollection:

public global::System.Collections.Specialized.StringCollection settingsName {
    get {
        return ((global::System.Collections.Specialized.StringCollection)(this["settingsName"]));
    }
    set {
        this["settingsName"] = value;
    }
}

但在分配 DefaultValue 后失败,出现上述错误消息。

我尝试在分配之前强制转换 XML 字符串,但当然也失败了。

在分配给设置属性之前,如何转换这样的 XML 字符串? 我需要做什么才能完成这项工作?

【问题讨论】:

    标签: c# visual-studio


    【解决方案1】:

    我意识到这是一个老问题,但如果有其他人像我一样来到这里,那么 OP 的解决方案就会奏效。然而,为了回答 OP 的最后一个问题,我怀疑微软正在使用 XmlSerializer 类,类似于我想出的这个扩展方法,虽然我也找不到一个简单的方法调用来为我做这件事:

        public static StringCollection ToStringCollection(this string str)
        {
            // Create an instance of the XmlSerializer.
            XmlSerializer serializer =
            new XmlSerializer(typeof(StringCollection));
    
            // Declare an object variable of the type to be deserialized.
            StringCollection sc;
    
            using (Stream reader = new MemoryStream(Encoding.Unicode.GetBytes(str)))
            {
                // Call the Deserialize method to restore the object's state.
                sc = (StringCollection)serializer.Deserialize(reader);
            }
    
            return sc;
        }
    

    以上基于https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer.deserialize?view=net-6.0的示例代码

    【讨论】:

      【解决方案2】:

      没人吗? 太糟糕了,我会认为有一个更优雅的解决方案......

      所以我现在正在使用它:

      1. 检查设置的Type是否为StringCollection

      2. 在“ArrayOfString/string”处读出 XML 元素

      ...

      public static void sReset(this Properties.Settings set, string key = "")
      {
          if (key == "")
          {
              set.Reset();
              return;
          }
          if (set.PropertyValues[key].Property.PropertyType == typeof(StringCollection))
          {
              string tvs = (string)set.PropertyValues[key].Property.DefaultValue;
              set.PropertyValues[key].PropertyValue = tvs.XmlToStringCollection();
              return;
          }
          set.PropertyValues[key].PropertyValue = set.PropertyValues[key].Property.DefaultValue;
      }
      
      public static StringCollection XmlToStringCollection(this string str)
      {
          StringCollection ret = new StringCollection();
      
          XmlDocument xmlDoc = new XmlDocument();
          xmlDoc.LoadXml(str);
          XmlNodeList terms = xmlDoc.SelectNodes("ArrayOfString/string");
      
          foreach (XmlElement s in terms)
          {
              if (s.InnerXml != "")
              {
                  Console.WriteLine("Found: " + s.InnerXml);
                  ret.Add(s.InnerXml);
              }
          }
          return ret;
      }
      

      因为 XML 看起来像这样:

      <?xml version="1.0" encoding="utf-16"?>
      <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <string>first string</string>
        <string>second string</string>
        <string>...</string>
      </ArrayOfString>
      

      ...真可惜,这该死的丑陋和有限:

      对于任何类型的 XML 序列化类型,您都必须这样做

      真的,我想要的是一种获取默认值的方法,就像 VS 一样。 我无法想象它会像这样 hacky,不是吗?

      【讨论】:

        猜你喜欢
        • 2011-12-01
        • 2016-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-19
        • 1970-01-01
        • 2021-06-30
        相关资源
        最近更新 更多