c#中管理复杂的字符串数组

本文关键字:字符串 数组 复杂 管理 | 更新日期: 2023-09-27 18:05:23

我想使用存储在web.config中的字符串数组来轻松更改其值,其格式为:full_w=670|small_w=100,q=low|tiny_h=30,c=true。每个模板被|(管道)分割,然后每个模板集由名称(在_的左边)和它对应的值(在_的右边)组成,值可以是几个,每个用,(逗号)分隔。我认为这可能符合3D数组的条件,我只是似乎找不到一种简单的方法来以一种明智的方式阅读它。任何想法或解决方案,最好的方式来读取/管理这个字符串的数据?

基本上,最后我希望能够调用模板small并读取其值,在本例中是width=100quality=low

c#中管理复杂的字符串数组

下面是我编写的解析这些设置字符串的函数:

public static Dictionary<string, Dictionary<string, string>> getSettings(string settingsStr)
{
    return settingsStr.Split('|').ToDictionary(
        template => template.Split('_')[0],
        template => template.Split('_')[1].Split(',').ToDictionary(
            setting => setting.Split('=')[0],
            setting => setting.Split('=')[1]));
}

它只是使用了大量的字符串.Split ting和.ToDictionary ing。

下面是测试,显示它可以工作:

var result = getSettings("full_w=670|small_w=100,q=low|tiny_h=30,c=true");
/*
result = {
    [ "full" => [ "w" => "670" ] ]
    [ "small" => [ "w" => "100", "q" => "low" ] ]
    [ "tiny" => [ "h" => "30", "c" => "true" ] ]
}
*/

要从模板small中读取wq的值,可以这样做:

int width = int.Parse(result["small"]["w"]);
string quality = result["small"]["q"];

编辑:作为一个额外的好处,如果您想将Dictionary<string, Dictionary<string, string>>转换回单个设置字符串,您可以使用以下方法:

public static string getSettingsStr(Dictionary<string, Dictionary<string, string>> settings)
{
    return string.Join("|",
        settings.Select(kvp =>
            kvp.Key + "_" + string.Join(",",
                kvp.Value.Select(setting =>
                    setting.Key + "=" + setting.Value))));
}

使用:

string settingsStr = getSettingsStr(result);
// settingsStr = "full_w=670|small_w=100,q=low|tiny_h=30,c=true"

如果要检查特定模板或设置是否存在,则使用.ContainsKey()方法:

// If I have "Dictionary<string, Dictionary<string, string>> settings;"
int width = -1;
string quality = null;
if (settings.ContainsKey("small"))
{
    if (settings["small"].ContainsKey("w"))
        width = int.Parse(settings["small"]["w"]);
    if (settings["small"].ContainsKey("q"))
        quality = settings["small"]["q"];
}

您是否考虑过在您自己的c#对象中使用普通的旧式XML序列化?下面是一个例子:

public class Program
{
    static void Main(string[] args)
    {
        var data = new MyConfig[2];
        for (int i = 0; i < 2; i++)
        {
            data[i] = new MyConfig { Name = "Name" + i };
            data[i].Properties = new MyConfigAttribute[]
            {
                new MyConfigAttribute { Name = "Property Name " + i, Value = "Property Value " + i },
                new MyConfigAttribute { Name = "2nd Property Name " + i, Value = "2nd Property Value " + i },
            };
        }
        var serializer = new XmlSerializer(typeof(MyConfig[]));
        using (StreamWriter tw = File.CreateText(@"c:'temp'myconfig.xml"))
        {
            serializer.Serialize(tw, data);
        }
        using (StreamReader tw = File.OpenText(@"c:'temp'myconfig.xml"))
        {
            var readBack = serializer.Deserialize(tw);
        }

        Console.ReadLine();
    }
    [XmlRoot("MY_CONFIG")]
    public class MyConfig
    {
        [XmlElement("NAME")]
        public string Name { get; set; }
        [XmlArray]
        [XmlArrayItem(typeof(MyConfigAttribute))]
        public MyConfigAttribute[] Properties { get; set; }
    }
    [XmlRoot("MY_CONFIG_ATTRIBUTE")]
    public class MyConfigAttribute
    {
        [XmlElement("ATTRIBUTE_NAME")]
        public string Name { get; set; }
        [XmlElement("ATTRIBUTE_VALUE")]
        public string Value { get; set; }
    }
}

基本上,您创建一个类来存储您的单个属性(在本例中为MyConfigAttribute),将其包装在另一个类中,为一组相关属性(在本例中为MyConfig)提供您的名称,然后使用普通XML序列化将设置写入单个XML文件,如代码

的这一部分
        var serializer = new XmlSerializer(typeof(MyConfig[]));
        using (StreamWriter tw = File.CreateText(@"c:'temp'myconfig.xml"))
        {
            serializer.Serialize(tw, data);
        }

可以使用下面这段代码再次将它读回对象:

        using (StreamReader tw = File.OpenText(@"c:'temp'myconfig.xml"))
        {
            var readBack = serializer.Deserialize(tw);
        }
这样做的好处是:
  • 易于理解和使用
  • 你可以在你的自定义类中添加特性,例如,向属性数组中添加值,从而在它周围包装一个自定义屏幕。

在Google上查找c# XML序列化!