【问题标题】:add to C# dictionary: cannot convert from 'string' to 'System.Collections.Specialized.NameValueCollection'添加到 C# 字典:无法从“字符串”转换为“System.Collections.Specialized.NameValueCollection”
【发布时间】:2017-04-26 08:38:34
【问题描述】:

我有一个数据源,其中包含 3 个不同的值,如下所示,

List<Configuration> lst = new List<Configuration>
        {
            new Configuration{Name="A", Config="X", Value="1"},
            new Configuration{Name="A", Config="X", Value="2"},
            new Configuration{Name="B", Config="Y", Value="2"}
        };

 public class Configuration
{
    public string Name { get; set; }
    public string Config { get; set; }
    public string Value { get; set; }
}

在这里,我想迭代整个源,并希望将“Name”值保留为 KEY,并将“Config”和“Value”保留为“NameValueCollection”。

为此,我正在使用如下字典,

var config = new Dictionary<string, NameValueCollection>();

但在添加到这本词典时,我遇到了 2 个问题,

foreach(var c in lst)
        {
            config.Add(c.Name, new NameValueCollection { c.Config, c.Value });
        }
  1. 重复键(Name="A")
  2. 这行给出错误,new NameValueCollection { c.Config, c.Value });

注意 - 我想要 X 的 1 和 2(以防重复键)

有没有更好的 C# 集合或如何解决上述错误。

谢谢!

【问题讨论】:

  • 如果存在重复键,您希望看到什么? 1 和 2 都代表 X?或者也许是最新值?我们不知道
  • 是的,1 和 2 都用于 X
  • 我很想知道您想用这种 NameValueCollection 方法解决什么样的问题。看来您的第一个数据结构 (List&lt;Configuration&gt;) 对于许多任务来说要好得多
  • 我没有像“List”这样的直接数据,NameValueCollection 用于其他目的(我们有重复的键 X 及其值 1 和 2)

标签: c#


【解决方案1】:

您可以使用lookups 的字典(它表示一个集合,其中键映射到多个值):

var config = lst.GroupBy(cfg => cfg.Name)
                .ToDictionary(g => g.Key, 
                              g => g.ToLookup(cfg => cfg.Config, cfg => cfg.Value));

配置类型将是

Dictionary<string, ILookup<string, string>>

访问值:

config["A"]["X"] // gives you IEnumerable<string> with values ["1","2"]

【讨论】:

  • 但我认为 OP 想要使用 NameValueCollection 作为值。我也缺少解释这种方法有什么问题
  • @TimSchmelter 我认为 OP 是在询问是否有更好的收藏可供使用:)
  • 我忽略了这句话,但我猜他正在寻找一个“更好”的集合,因为我们可以帮助修复这个错误
  • @TimSchmelter 问题中有一个“或”连词 - 是否有更好的 C# 集合或如何解决上述错误。 :) 所以...我选择了第一部分回答
【解决方案2】:

试试这个:

        List<Configuration> lst = new List<Configuration>
        {
            new Configuration{Name="A", Config="X", Value="1"},
            new Configuration{Name="A", Config="X", Value="2"},
            new Configuration{Name="B", Config="Y", Value="2"}
        };
        var config = new Dictionary<string, NameValueCollection>();
        NameValueCollection temp = new NameValueCollection();
        foreach (var c in lst)
        {
            if(config.TryGetValue(c.Name, out temp)){
                config[c.Name].Add(c.Config,c.Value);
            }
            else{
                config.Add(c.Name, new NameValueCollection { {c.Config,c.Value } });
            }
        }

【讨论】:

  • 不幸的是,这是低效的。如果您查找键,字典非常有效。但是您使用从Keys 属性返回的集合。此属性用所有键填充集合。然后config.Keys.Contains(c.Name) 将此集合中的所有字符串与给定名称O(n) 进行比较。所以你失去了字典的查找性能。而是使用config.TryGetValue
  • 谢谢@TimSchmelter! :)
  • if的正文不正确,应该是:config[c.Name].Add(c.Config, c.Value);。但更好的是:temp.Add(c.Config, c.Value) 避免再次查找
【解决方案3】:

NameValueCollection 包含多个名称和值,因为它是一个集合。所以你不能以你的方式初始化它。但是您可以使用它将所有重复的Names 分组到同一个集合中。我会使用Dictionary&lt;k,v&gt;.TryGetValue:

var config = new Dictionary<string, NameValueCollection>();

foreach (Configuration c in lst)
{
    NameValueCollection nvc;
    if(!config.TryGetValue(c.Name, out nvc))
    {
        nvc = new NameValueCollection();
        config.Add(c.Name, nvc);
    }
    nvc.Add(c.Config, c.Value);
}

【讨论】:

  • TryGetValue 是否比ContainsKey 更高效?为什么不只是if(!config.ContainsKey(c.Name))
  • 因为如果要向 NameValueCollection 添加新项,则需要再次查找。
【解决方案4】:

试试这个: 在 Dictionary 类中无需检查值是否重复; 如果它是第一次将被添加。 如果是第二次就会更新。

   List<Configuration> lst = new List<Configuration>
    {
        new Configuration{Name="A", Config="X", Value="1"},
        new Configuration{Name="A", Config="X", Value="2"},
        new Configuration{Name="B", Config="Y", Value="2"}
    };
        var config = new Dictionary<string, NameValueCollection>();
        foreach (var c in lst)
        {
            config[c.Name] = new NameValueCollection { { c.Config, c.Value } };

        }

【讨论】:

    猜你喜欢
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多