在 Visual Studio .NET 中获取用户设置集合类型的默认值

Posted

技术标签:

【中文标题】在 Visual Studio .NET 中获取用户设置集合类型的默认值【英文标题】:Getting user settings collection types' default values in 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 字符串? 我需要做什么才能完成这项工作?

【问题讨论】:

【参考方案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】:

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

所以我现在正在使用它:

    检查设置的Type是否为StringCollection

    在“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,不是吗?

【讨论】:

以上是关于在 Visual Studio .NET 中获取用户设置集合类型的默认值的主要内容,如果未能解决你的问题,请参考以下文章

用Visual Studio 连接数据库并获取DataSet的方法

在 Visual Studio .NET 中获取用户设置集合类型的默认值

visual studio 2015 和.net 啥区别

如何用visual studio 查看.net类库

用Visual Studio建立第一个ASP.NET页面

visual studio .net的安装问题