【问题标题】:A list of string tables c#字符串表列表 c#
【发布时间】:2015-06-18 22:49:05
【问题描述】:

我的 c# 脚本有问题。我想创建一个字符串表列表,如下所示:

public List<string[]> Signals = new List<string[]>(); 
public string[] Communication  =  new string[3];

所以它应该看起来像这样,我的列表中应该有几个 Communication 实例:Signals = (Communication1, Communication2, ...) 并且每个 Communication 有 3 个字符串字段。

当我收集了我的 3 个通信数据时(每次通信都不同):

Communication[0]=CommunicationType;
Communication[1]=CommunicationTime;
Communication[2]=CommunicationName;

我将它们存储到我的列表中:

Signals.Add(Communication); // I have also tried .Insert with different Indexes

当我这样做了几次,储备了 6 个不同的通信表时,我想最终看到我的每一个通信实例,所以我这样做:

foreach (string[] Signal in Signals)
{
    foreach (string CommunicationUnit in Signal)
    {
        Print(CommunicationUnit);
    }
}

我所看到的输出是列表中最后一个元素的 6 倍,如下所示

ARINC3

121us

Comm6

ARINC3

121us

Comm6

ARINC3

121us

Comm6

ARINC3

121us

Comm6

ARINC3

121us

Comm6

ARINC3

121us

Comm6

当我认为我会看到列表中的每个元素实际上是 6 个不同的字符串表时。

我不明白我的脚本有什么问题。我认为错误出在 foreach 循环的某个地方。

【问题讨论】:

  • 使用类而不是string[]
  • 我的心理调试技能告诉我,您正在为所有 6 个重复使用相同的 Communication 数组,因此它们都显示最后的数据,因为它们共享相同的引用。您最好按照其他人的建议创建一个类来为您的数据结构建模。
  • 您没有显示有问题的代码。显示使用通信数组填充信号列表的完整代码。当你这样做时,很明显你没有为每个 List 元素创建一个新数组。相反,您会一遍又一遍地使用对同一数组的引用来填充列表。

标签: c#


【解决方案1】:

重新创建一个简单的例子:(当你在插入后实例化一个新的字符串数组时它会起作用)

List<string[]> Signals = new List<string[]>(); 
string[] Communication  =  new string[3];

Communication[0] = "a";
Communication[1] = "b";
Communication[2] = "c";

Signals.Add(Communication);

Communication = new string[3];

Communication[0] = "d";
Communication[1] = "e";
Communication[2] = "f";

Signals.Add(Communication);

foreach (string[] Signal in Signals)
{
    foreach (string CommunicationUnit in Signal)
    {
        Console.WriteLine(CommunicationUnit);
    }
}

【讨论】:

  • 为什么foreach中的foreach?让communicationUnit 在信号中循环可能更容易吗?
  • 你也可以这样做Signals.SelectMany(x =&gt; x).ToList().ForEach(Console.WriteLine);,但我怀疑这会让他更容易理解。
  • HAHAHAHA XD,但仍然想知道为什么要创建一个列表并将其放入一个字符串[]。我的意思是你可以通过 list 循环,它比 2 个循环容易得多
【解决方案2】:

您似乎只是在列表中添加了 6 次相同的 Communication 对象。

如果您将对象存储在列表中,您只需存储对它的引用,而不是副本。

那么,如果您将第一个通信项添加到列表中,然后对其进行修改并再次添加,您将在内存中对同一对象进行两次相同的引用。

这意味着,如果您更新您的通信项目,您只会更新您列表中的所有引用。

您必须为每个项目创建一个新的通信项。

Signals.Add(new string[3] {
    CommunicationType,
    CommunicationTime,
    CommunicationName
});
Signals.Add(new string[3] {
    CommunicationType2,
    CommunicationTime2,
    CommunicationName2
});

string[] Communication  =  new string[3];
Communication[0]=CommunicationType;
Communication[1]=CommunicationTime;
Communication[2]=CommunicationName;
Signals.Add(Communication);
string[] Communication2  =  new string[3];
Communication2[0]=CommunicationType;
Communication2[1]=CommunicationTime;
Communication2[2]=CommunicationName;
Signals.Add(Communication2);

如果你使用同一个对象,你只会覆盖它的数据。

【讨论】:

  • 这里很可能是这种情况
  • 好的,感谢您向我解释这一点,但正如您所说,如果每次我覆盖通信我实际上在我的所有列表中写入相同的数据,为什么在每次插入后重置通信时它会工作使用通讯=新字符串[3]; ?
  • 因为当您使用“new”关键字时,它会创建一个新对象,然后创建一个新引用。但是您以前的对象仍在内存中,因为您的列表仍在使用它。如果您使用“通信”,您将无法再访问它。
  • 如果您想了解更多信息,可以查看dotnetperls.com/newalbahari.com/valuevsreftypes.aspx
【解决方案3】:

输出正确:前 3 行输出是您的第一个表(或 Signals.First())

ARINC3 <- CommunicationType
121us  <- CommunicationTime
Comm6  <- CommunicationName

就像您在表格中输入它们一样。你有 6 个表格,每个表格 3 行,所以 18 行。

【讨论】:

    【解决方案4】:

    在你的类中创建一个带有通信列表的属性并删除字符串数组。

    比使用 Signal 类中的列表添加通信。

    【讨论】:

      【解决方案5】:

      只要保持简单和干净,不要让自己太难就够难了。

      我只使用 1 个 foreach 循环而不是 2 个,并且不创建多个列表。我只有列表,然后在我的 foreach 中查看它

      List<string[]> Signals = new List<string[]>(); 
          string[] Communication  =  new string[3];
      
      Communication[0] = "a";
      Communication[1] = "b";
      Communication[2] = "c";
      
      Signals.Add(Communication);
      i
      foreach (string CommunicationUnit in Signals)
      {
          Console.Writeline(CommunicationUnit[i]);
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-13
        • 2013-01-03
        • 2021-06-23
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2020-08-02
        相关资源
        最近更新 更多