C# - 无法根据文本文件数据在列表中添加元素(这是一个列表)

C# - Unable to add elements (which is a list) in a list according to text file data

我正在开发 C# winForm 应用程序。在我的项目中,我需要读取文本文件。并获取列表中的数据。

对于测试:使用 "listTest" 列表

对于 cmd : 使用 "listCmd" 列表

我的要求是:我需要 mainList 中的 Test1 和 Test2 "listTest"。在 Test1 -> cmd1、cmd2、cmd3(在 listCmd 中)。在 cmd1 -> tx,rx 中。与 Test2 相同。

文本文件数据

Test:Test1
cmd-1:5A 02 11 00 02 3A 05 ||5A 02 01 02 3A 3F  
cmd-2:5A 02 31 00 02 3E 00 80||5A 02 01 02 3E 43  
cmd-3:5A 02 21 00 02 00||5A 02 01 02 0B 10     
Test:Test2
cmd-1:5A 02 11 00 02 3A 05 00 14 00 42||5A 02 01 02 3A 3F  
cmd-2:5A 02 31 00 02 3E 00 00 02 00 80||5A 02 01 02 3E 43  

我的问题:我尝试了以下代码,其中,我得到了 Test1 的所有 5 个 cmd 值。 Test2 也一样。我只想要 Test1 中的 3 cmd 和 Test2 中的 2 cmd。 .

在class-1:

private void readCmd()
    {
        string cmdfile = System.IO.Directory.GetCurrentDirectory()  + "\Cmd.txt";   
        try
        {
            string[] lines = File.ReadAllLines(cmdfile); 
            string[] splitLine;
            string[] txRx;

            cls_test testnum = new cls_test();
            str_listcmd listcmd = new str_listcmd();

            foreach (string line in lines)
            { 
                if (line.Contains("Test"))
                {
                    splitLine = line.Split(':');
                    txRx = splitLine.Skip(1).ToArray();   
                    uc.listTest.Add(testnum); 
                }

                if (line.Contains("cmd"))
                {
                    string[] delimiter = { ":", "||" };
                    txRx = line.Split(delimiter, StringSplitOptions.None);
                    listcmd.cmdNo = txRx[0];
                    listcmd.txCmd = txRx[1];
                    listcmd.rxCmd = txRx[2];
                    testnum.listCmd.Add(listcmd);
                }  
            }

            for (int j = 0; j < uc.listTest.Count; j++)
            {
                for (int i = 0; i < uc.listTest[j].listCmd.Count; i++)
                {
                string tx = uc.listTest[j].listCmd[i].txCmd;
                string rx = uc.listTest[j].listCmd[i].rxCmd;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

在Class-2中,声明了主列表

 public List<cls_test> listTest = new List<cls_test>();  //main list


 struct str_listcmd
 {
   public string cmdNo { get; set; }
   public string txCmd { get; set; }
   public string rxCmd { get; set; }
 }
 class cls_test
 {
    public List<str_listcmd> listCmd = new List<str_listcmd>();
 }


 private void button1_Click(object sender, EventArgs e)
 {
            var a = listTest;
 } 

我找不到我遗漏的东西。请帮我解决这个问题。提前致谢。

事实上,您可以重构代码以使其更加结构化,从而减少潜在错误并提高可测试性。为了解决您当前的问题,只需更换如下代码即可;

// ...
// ...
cls_test testnum = null; // <= Leave as NULL at the beginning
str_listcmd listcmd = new str_listcmd();

foreach (string line in lines)
{
    if (line.Contains("Test"))
    {
        testnum = new cls_test(); // <= Init object for each Test line
        // ...
        // ...

当你读一个cmd时,你总是把它赋值给testnum

testnum.listCmd.Add(listcmd);

但是当您阅读 "Test" 行时,您不会创建新的测试编号,因此所有 cmd 都会分配给同一个测试。

我认为测试线部分应该如下所示:

            if (line.Contains("Test"))
            {
                splitLine = line.Split(':');
                txRx = splitLine.Skip(1).ToArray();   
                testnum = new cls_test();
                uc.listTest.Add(testnum); 
            }

我不确定为什么这部分会更改 txRx。

总的来说,这是相当混乱的代码。我认为您应该在循环内移动 splitLine、rxTx 和 listCmd,以表明它们的值不会从一行转移到下一行。