这是方法体中多键字典的有效代码吗?

本文关键字:有效 代码 字典 方法 | 更新日期: 2023-09-27 18:08:28

我只是想问一下:

  1. 下面的代码有效吗?
  2. 有更好的方法来处理这个问题吗?
  3. 如何编码,如果额外的值表名/字段名对是需要的?

我们需要使用包含类似(TableName, FieldName, FieldValue)的多键字典。

我搜索了一些答案,但是到目前为止我找到的答案并不适用于我们的设置。我们使用的是3.5,所以还没有Tuple可用。我们还将这个脚本逻辑集成到一个只允许在方法体内部编码的应用程序中,因此我们受到限制,不能创建单独的类/结构等。我们的设置是c#/VS 2010。

任何帮助都是感激的。提前感谢!

Dictionary<string, Dictionary<string, string>> tableList = new Dictionary<string, Dictionary<string, string>>();
Dictionary<string, string> fieldList = new Dictionary<string, string>();
// add fields to field list, then add the field lists to the corresponding table list
// clear field list for next table
// values are just hardcoded here to simplify, but is being read from actual objects in the application
fieldList.Add("Field1", "abc");
fieldList.Add("Field2", "def");
fieldList.Add("Field3", "ghi");
fieldList.Add("Field4", "jkl");
tableList.Add("Table1", new Dictionary<string, string>(fieldList));
fieldList.Clear();
fieldList.Add("Field1", "xyz");
fieldList.Add("Field2", "uvw");
fieldList.Add("Field3", "rst");
tableList.Add("Table2", new Dictionary<string, string>(fieldList));
fieldList.Clear();
fieldList.Add("Field1", "123");
fieldList.Add("Field2", "456");
tableList.Add("Table3", new Dictionary<string, string>(fieldList));
fieldList.Clear();
// Display tables and corresponding fields                          
foreach (KeyValuePair<string, Dictionary<string, string>> fieldList4 in tableList)
{
    foreach (KeyValuePair<string, string> fieldList5 in fieldList4.Value)
    {
        txtMessage.Text = txtMessage.Text + "'r'nTable=" + fieldList4.Key + ", Field=" + fieldList5.Key + " - " + fieldList5.Value;
    }
}
// Try to find tables and fields in the lists, and list the value if found
string tableToFind = "Table2";
string fieldToFind = "Field2";
Dictionary<string, string> tableFields = new Dictionary<string, string>();
if (tableList.Keys.Contains(tableToFind) == true)
{
    txtMessage.Text = txtMessage.Text = "'r'nTable=" + tableToFind + " exist in table list";
    tableList.TryGetValue(tableToFind, out tableFields);
    if (tableFields.Keys.Contains(fieldToFind) == true)
    {
        foreach(KeyValuePair<string, string> fieldData  in tableFields)
        {
            if (fieldData.Key == fieldToFind)
            {
                txtMessage.Text = txtMessage.Text + "'r'nTable=" + tableToFind + ", Field=" +  fieldData.Key + 
                                                    " with value=" + fieldData.Value + " exist in table list";
                break;
            }
        }
    }
}

这是方法体中多键字典的有效代码吗?

您可以使用编译器为您创建组合键:使用匿名类型

var dictionary = new Dictionary<Object, int>();
dictionary.Add(new{Text="A", Number=1}, 1);
dictionary.Add(new{Text="A", Number=2}, 3);
dictionary.Add(new{Text="B", Number=1}, 4);
dictionary.Add(new{Text="B", Number=2}, 5);
var x = dictionary[new{Text="B", Number=2}];
c#将根据你的字段实现Equals和GetHashcode。因此,您将获得一个键,它将按照您的期望运行。

你的代码中有一大堆问题和低效率。

  1. 如果你要创建多个字典,直接创建字典。不要使用单独的实例来填充值并从。

  2. 永远不要在这样的循环中使用字符串连接。使用StringBuilder或其他类似的机制来建立你的字符串。你已经在集合中有了你的值,所以使用String.Join()和LINQ将清理它。

  3. 你从字典中获取值的方法至少可以说是尴尬的。通常情况下,您将单独使用TryGetValue()来尝试读取密钥。您的代码不正确地使用它。如果要检查键是否存在于字典中(使用Contains()),那么使用TryGetValue()就没有意义了。更糟糕的是,您这样做,然后通过遍历键值对在内部字典中手动搜索键。

典型的模式是这样的:

DictValueType value;
if (myDict.TryGetValue(key, out value))
{
    // key was in the dictionary, the value is stored in the `value` variable
}

你的代码可以写得更更有效,像这样:

var tableList = new Dictionary<string, Dictionary<string, string>>
{
    { "Table1", new Dictionary<string, string>
                {
                    { "Field1", "abc" },
                    { "Field2", "def" },
                    { "Field3", "ghi" },
                    { "Field4", "jkl" },
                }
    },
    { "Table2", new Dictionary<string, string>
                {
                    { "Field1", "xyz" },
                    { "Field2", "uvw" },
                    { "Field3", "rst" },
                }
    },
    { "Table3", new Dictionary<string, string>
                {
                    { "Field1", "123" },
                    { "Field2", "456" },
                }
    },
};
// Display tables and corresponding fields
txtMessage.Text = String.Join("'r'n",
    tableList.SelectMany(table =>
        table.Value.Select(fieldList =>
            String.Format("Table={0}, Field={1} - {2}",
                table.Key, fieldList.Key, fieldList.Value)
        )
    ).ToArray()
);
// (I hope you have this in a separate method)
// Try to find tables and fields in the lists, and list the value if found
string tableToFind = "Table2";
string fieldToFind = "Field2";
var builder = new StringBuilder(txtMessage.Text); // mostly useful if you have a 
                                                  // lot of different strings to add
Dictionary<string, string> foundTable;
if (tableList.TryGetValue(tableToFind, out foundTable))
{
    builder.AppendLine()
        .Append("Table=" + tableToFind + " exist in table list");
    string foundField;
    if (foundTable.TryGetValue(fieldToFind, out foundField))
    {
        builder.AppendLine()
            .AppendFormat("Table={0}, Field={1} with value={2} exist in table list",
                tableToFind, fieldToFind, foundField);
    }
}
txtMessage.Text = builder.ToString();

嵌套字典不是一件坏事,它是组织键和值层次结构的好方法。但是为了保持它的可维护性,通常应该将所有内容封装在另一个类中,提供操作数据的方法,而不必直接管理字典。您可以使它既高效又可维护。如何实现这一点是留给你的练习。

我不认为这么多字典是"有效的"。

我认为最好的方法是将值多次添加到同一个字典中—假设您希望能够根据其中一个索引(而不是全部)对它们进行索引:

dictionary.Add("FField1", "xxx");
dictionary.Add("TTable1", "xxx");

如果您想根据所有索引一起对它们进行索引,则使用连接字符(如''0')。

dictionary.Add("Table1'0Field1", "xxx");