C# 存储字典<;字符串,字符串>;在应用程序设置中

C# 存储字典<;字符串,字符串>;在应用程序设置中,c#,.net-3.5,dictionary,settings,C#,.net 3.5,Dictionary,Settings,我有一个字符串字典,我希望用户能够添加/删除其中的信息,然后为他们存储这些信息,以便他们可以在下次程序重新启动时访问这些信息 我不清楚如何将字典存储为设置。我看到在system.collections.special下有一个东西叫做stringdictionary,但我读到SD已经过时,不应该使用 此外,将来我可能需要存储一个不仅仅是字符串的字典(int string) 如何在.net应用程序的设置文件中存储词典?最简单的答案是使用行和列分隔符将词典转换为单个字符串。然后,您只需要在设置文件中存

我有一个字符串字典,我希望用户能够添加/删除其中的信息,然后为他们存储这些信息,以便他们可以在下次程序重新启动时访问这些信息

我不清楚如何将字典存储为设置。我看到在system.collections.special下有一个东西叫做stringdictionary,但我读到SD已经过时,不应该使用

此外,将来我可能需要存储一个不仅仅是字符串的字典(int string)


如何在.net应用程序的设置文件中存储词典?

最简单的答案是使用行和列分隔符将词典转换为单个字符串。然后,您只需要在设置文件中存储1个字符串。

除了执行以下操作之外,我还将为字典寻找其他存储。设置对象最终会序列化到磁盘。

您可以创建一个自定义类,将字典作为公共属性公开。然后可以将此自定义类型指定为设置的类型

编辑:

我刚刚读到,由于某种原因,通用字典不能被XML序列化,因此我的解决方案可能无法工作(尽管我还没有测试过…)。这很奇怪,因为泛型列表可以毫无问题地序列化


您仍然可以创建可设置为用户设置的自定义类,但需要将列表作为属性而不是字典公开。

您考虑过使用XML存储字典吗?如果将来您决定能够存储其他类型的词典,那么这将提供一定的扩展性。您可能会这样做:

<dictionary>
   <entry key="myKey">
      [whatever data you like]
   </entry>
</dictionary>

[您喜欢的任何数据]

这可能有点过分,但如果您想存储更复杂的数据,如自定义对象,您也需要做好准备。

您还可以使用System.Collections.Specialized.StringCollection,方法是将键放在偶数索引上,将值放在奇数索引上

/// <summary>
/// Emulate a Dictionary (Serialization pb)
/// </summary>
private static string getValue(System.Collections.Specialized.StringCollection list, string key)
{
    for (int i = 0; i * 2 < list.Count; i++)
    {
        if (list[i] == key)
        {
            return list[i + 1];
        }
    }
    return null;
}

/// <summary>
/// Emulate a Dictionary (Serialization pb)
/// </summary>      
private static void setValue(System.Collections.Specialized.StringCollection list, string key, string value)
{
    for (int i = 0; i * 2 < list.Count; i++)
    {
        if (list[i] == key)
        {
            list[i + 1] = value;
            return;
        }
    }
    list.Add(key);
    list.Add(value);
}
//
///模拟字典(序列化pb)
/// 
私有静态字符串getValue(System.Collections.Specialized.StringCollection列表,字符串键)
{
for(int i=0;i*2
编辑:这将返回一个哈希表(无论出于何种原因,尽管是“DictionarySectionHandler”)。然而,由于哈希表和字典是如此相似,这应该不是一个大问题(尽管我意识到字典是更新的、参数化的,等等;我自己更喜欢dicitonaries,但这是.NET给我们的)



我刚刚找到的最好的答案是。它返回一个typesafe集合,在转换它的代码中没有任何混乱,并且您在.config文件中创建了一个明显(且简单)的集合。我正在使用它,这对于任何未来的程序员(包括你自己)来说都是非常直接的。它允许更强的类型和更大的灵活性,而不需要任何过于复杂和不必要的解析

您可以存储
StringCollection
。这是相似的

我使用了两种扩展方法在
StringCollection
字典
之间进行转换。这是我能想到的最简单的方法

public static class Extender
{
    public static Dictionary<string, string> ToDictionary(this StringCollection sc)
    {
        if (sc.Count % 2 != 0) throw new InvalidDataException("Broken dictionary");

        var dic = new Dictionary<string, string>();
        for (var i = 0; i < sc.Count; i += 2)
        {
            dic.Add(sc[i], sc[i + 1]);
        }
        return dic;
    }

    public static StringCollection ToStringCollection(this Dictionary<string, string> dic)
    {
        var sc = new StringCollection();
        foreach (var d in dic)
        {
            sc.Add(d.Key);
            sc.Add(d.Value);
        }
        return sc;
    }
}

class Program
{
    static void Main(string[] args)
    {
        //var sc = new StringCollection();
        //sc.Add("Key01");
        //sc.Add("Val01");
        //sc.Add("Key02");
        //sc.Add("Val02");

        var sc = Settings.Default.SC;

        var dic = sc.ToDictionary();
        var sc2 = dic.ToStringCollection();

        Settings.Default.SC = sc2;
        Settings.Default.Save();
    }
}
公共静态类扩展器
{
公共静态字典ToDictionary(此StringCollection sc)
{
如果(sc.Count%2!=0)抛出新的InvalidDataException(“断字典”);
var dic=新字典();
对于(变量i=0;i
您可以使用从StringDictionary派生的此类。为了对应用程序设置有用,它实现了IXmlSerializable。 或者,您也可以使用类似的方法来实现自己的XmlSerializable类

public class SerializableStringDictionary : System.Collections.Specialized.StringDictionary, System.Xml.Serialization.IXmlSerializable
{
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        while (reader.Read() &&
            !(reader.NodeType == System.Xml.XmlNodeType.EndElement && reader.LocalName == this.GetType().Name))
        {
            var name = reader["Name"];
            if (name == null)
                throw new FormatException();

            var value = reader["Value"];
            this[name] = value;
        }
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        foreach (System.Collections.DictionaryEntry entry in this)
        {
            writer.WriteStartElement("Pair");
            writer.WriteAttributeString("Name", (string)entry.Key);
            writer.WriteAttributeString("Value", (string)entry.Value);
            writer.WriteEndElement();
        }
    }
}
生成的XML片段将类似于:

...
<setting name="PluginSettings" serializeAs="Xml">
    <value>
        <SerializableStringDictionary>
            <Pair Name="property1" Value="True" />
            <Pair Name="property2" Value="05/01/2011 0:00:00" />
        </SerializableStringDictionary>
    </value>
</setting>
...
。。。
...

如果不需要使用设置设计器或使用文本编辑器编辑设置,则可以创建一个简单的类,该类派生自ApplicationSettingsBase

namespace MyNamespace
{
    using System.Collections.Generic;
    using System.Configuration;

    /// <summary>
    /// Persistent store for my parameters.
    /// </summary>
    public class MySettings : ApplicationSettingsBase
    {
        /// <summary>
        /// The instance lock.
        /// </summary>
        private static readonly object InstanceLock = new object();

        /// <summary>
        /// The instance.
        /// </summary>
        private static MySettings instance;

        /// <summary>
        /// Prevents a default instance of the <see cref="MySettings"/> class 
        /// from being created.
        /// </summary>
        private MySettings()
        {
            // don't need to do anything
        }

        /// <summary>
        /// Gets the singleton.
        /// </summary>
        public static MySettings Instance
        {
            get
            {
                lock (InstanceLock)
                {
                    if (instance == null)
                    {
                        instance = new MySettings();
                    }
                }

                return instance;
            }
        }

        /// <summary>
        /// Gets or sets the parameters.
        /// </summary>
        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Binary)]
        public Dictionary<string, string> Parameters
        {
            get
            {
                return (Dictionary<string, string>)this["Parameters"];
            }

            set
            {
                this["Parameters"] = value;
            }
        }
    }
}

如果您想将字典序列化为用户可编辑的内容,则必须从字典派生并使用TypeConverter(请参阅)。

好主意-使用类似JSON序列化的内容使此过程相对轻松。您能稍微了解一下吗?JSON序列化的形式为{“对象”:{“键”:“值”,“键”:“值”}}在野外有JSON序列化库——你不必从头开始做这件事;但是如果你想,写一个非常简单的应该不会太难。类似但更简单的是使用StringCollection(可以存储为设置)。然后,只需将键与值分开(不要使用“\0”-即.Net集合)
// this code untested...
MySettings.Instance.Parameters["foo"] = "bar";
MySettings.Instance.Parameters.Save();
MySettings.Instance.Parameters.Reload();
string bar;
if (!MySettings.Instance.Parameters.TryGetValue("foo", out bar))
{
    throw new Exception("Foobar");
}