c#字典从键

时间:2016-09-23 15:24:18

标签: c# dictionary

我一直在这里搜索,我发现以前曾经问过类似的问题,而且我已经过了几次,但看起来似乎是正确的似乎没有用。

我有以下方法在从SQL查询收集的DataSet中提取一组键值对。

    public static Dictionary<string, string> LoadConfiguration()
    {
        DataSet sqlResults = data.GetSettings();

        Dictionary<string, string> dict = 
            new Dictionary<String, String>();

        foreach (DataRow dr in sqlResults.Tables[0].Rows)
        {
            dict.Add(
                dr.Field<string>("key"), dr.Field<string>("value")
                    );
        }

        return dict;
    }

就我所能看到的那样简单,但我以前从未真正使用过字典,因为我对任何类型的真实编程都比较新。

我知道我的词典有预期的数据,因为如果我用foreach迭代它,它会给我预期的结果

    foreach (KeyValuePair<string, string> i in MyStuff.Configuration.LoadConfiguration())
    {
        Console.WriteLine("Key = " + i.Key + " Value = " + i.Value);
    }

给了我以下这是迄今为止我已经实现的所有内容

  

Key = EnableLdap Value = false   Key = LdapPath Value = LDAP:// DC = some,DC = domain,DC = com   Key = SessionTimeout Value = 60

但我只想从名为EnableLdap的键中选择一个特定值,例如

我的理解是以下两种方法都是正确的。但是当我尝试这种方式时,我得到一个KeyNotFoundException

    Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
    Console.WriteLine(dict["EnableLdap"]);

如果我尝试这个,我得到[InvalidOperationException:Sequence不包含匹配元素]

    Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
    Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value);

如果我尝试这个,我就什么也得不到

    string value = "";

    if (dict.TryGetValue("EnableLdap", out value))
    {
        dict["EnableLdap"] = value;
        Console.WriteLine(value);

    }

我很确定我在这里缺少一些简单的东西,答案会产生一个facepalm

解决方案:

我被尾随空格抓住了,正如评论中建议的那样。解决方案是在将它们添加到我的词典时简单地为我的行值添加一些修剪。

public static Dictionary<string, string> LoadConfiguration()
{
    DataSet sqlResults = data.GetSettings();

    Dictionary<string, string> dict = 
        new Dictionary<String, String>();

    foreach (DataRow dr in sqlResults.Tables[0].Rows)
    {
        dict.Add(
            dr.Field<string>("key").Trim(), dr.Field<string>("value").Trim()
                );
    }

    return dict;
}

2 个答案:

答案 0 :(得分:4)

这是这两个问题之一。

  1. 字典中不存在密钥,这可能是由于拼写错误甚至是前导/尾随空格或某种性质的原因。
  2. 密钥存在,但其设置与您认为的不同。
  3. 对于选项2,您可以通过在构造函数中为字典提供StringComparer来确保套管不是问题。

    Dictionary<string, string> dict = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
    

    上面的代码片段将确保字典根据字符串键的序数不区分大小写表示为每个键创建哈希。这将允许以下示例通过:

    dict["enableldap"] = "true";
    Console.WriteLine(dict["EnableLdap"]);
    

    有关更多选项,请参阅StringComparer

答案 1 :(得分:0)

我的理解是以下两种方法都是正确的。但是当我尝试这种方式时,我得到一个KeyNotFoundException

您的词典似乎没有该密钥。请记住,词典对键是敏感的,您可以使用此方法检查键是否存在:

Console.WriteLine("Exist key "+ dict.ContainsKey("EnableLdap"));

如果我试试这个,我得到一个[InvalidOperationException:Sequence不包含匹配的元素]

  Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration();
    Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value);

linQ方法.Single期望找到一个值。如果没有找到值,则抛出Exception。如果您不想要该异常,则应该使用.SingleOrDefault,但要注意空值。

如果我尝试这个,我就什么也得不到

TryGetValue不会抛出任何异常。它只是尝试。

我建议您在创建字典时为大键或小写键添加格式。

foreach (DataRow dr in sqlResults.Tables[0].Rows)
        {
            dict.Add(
                dr.Field<string>("key").ToUpperCase(), dr.Field<string>("value")
                    );
        }

然后你不能这样查询:

if(dict.ContainsKey("ENABLELDAP"))
{
   string value = dict["ENABLELDAP"];
}