【问题标题】:Elements in list are getting overwritten when adding to list添加到列表时,列表中的元素被覆盖
【发布时间】:2020-08-28 17:32:30
【问题描述】:

我正在从 XML 文件中读取标签和值,以获取功能测试软件所需的信息。将频率添加到列表时,所有其他现有列表项的频率都会被新频率覆盖。

public struct Configuration 
{
    public string Description;
    public byte Mode;
    public byte Deviation;
    public string PartNumber;
    public UInt16[] Frequencies;
    public byte TxPower;
    public byte PWM;
    public Int16 HeaterSetpoint;
    public string FirmwareVersion;
    public bool Active;
    public int Threshold;
} // struct Configuration

Configurations = new List<Configuration>();
ushort[] Frequencies = new ushort [7];
Configuration TestConfig = new Configuration();

/*Open the XML file, load all the tag values into XmlNodeList */
//Pull in all the XML Tag Values Sorted by Tag Name
XmlNodeList xml_description = ConfigFile.GetElementsByTagName("description");
XmlNodeList xml_mode = ConfigFile.GetElementsByTagName("mode");
XmlNodeList xml_deviation = ConfigFile.GetElementsByTagName("deviation");
XmlNodeList xml_partnumber = ConfigFile.GetElementsByTagName("partnumber");
XmlNodeList xml_channel0 = ConfigFile.GetElementsByTagName("channel0");
XmlNodeList xml_channel1 = ConfigFile.GetElementsByTagName("channel1");
XmlNodeList xml_channel2 = ConfigFile.GetElementsByTagName("channel2");
XmlNodeList xml_channel3 = ConfigFile.GetElementsByTagName("channel3");
XmlNodeList xml_channel4 = ConfigFile.GetElementsByTagName("channel4");
XmlNodeList xml_channel5 = ConfigFile.GetElementsByTagName("channel5");
XmlNodeList xml_channel6 = ConfigFile.GetElementsByTagName("channel6");
XmlNodeList xml_txpower = ConfigFile.GetElementsByTagName("txpower");
XmlNodeList xml_pwm = ConfigFile.GetElementsByTagName("pwm");
XmlNodeList xml_hsp = ConfigFile.GetElementsByTagName("hsp");
XmlNodeList xml_firmware = ConfigFile.GetElementsByTagName("firmware");
XmlNodeList xml_active = ConfigFile.GetElementsByTagName("active");
XmlNodeList xml_threshold = ConfigFile.GetElementsByTagName("threshold");

/*Use LINQ to check that the XmlNodeLists are all the same length. This way we don't try and load invalid data*/

if(!listsaresamelength)
{
    /*Alert user there is a problem with the XML file and close the application*/
}

//Loop to add values to the List
for(i = 0; i < NumberofXmlValues; i++)
{
    /*check that the description, Mode, Deviation are valid and add them to DummyConfig*/

    try
    {
        Frequencies[0] = UInt16.Parse(xml_channel0[i].InnerText);
        Frequencies[1] = UInt16.Parse(xml_channel1[i].InnerText);
        Frequencies[2] = UInt16.Parse(xml_channel2[i].InnerText);
        Frequencies[3] = UInt16.Parse(xml_channel3[i].InnerText);
        Frequencies[4] = UInt16.Parse(xml_channel4[i].InnerText);
        Frequencies[5] = UInt16.Parse(xml_channel5[i].InnerText);
        Frequencies[6] = UInt16.Parse(xml_channel6[i].InnerText);
        //Move the frequencies to the list
        TestConfig.Frequencies = Frequencies;
    }

    catch 
    {
        /*Problem with the XML file. Alert the user and close the application*/
    }

    /*check that the heater set point, PWM set point, partnumber, Txpower, and Threshold are valid and add them to DummyConfig*/

    Configurations.Add(TestConfig)

}

for 循环的第一次迭代运行良好;结果如下: first loop iteration second loop iteration

我尝试了几种不同的方法来更改我写入列表的方式,但它们都产生了相同的结果。我觉得我错过了一些明显的东西。

【问题讨论】:

  • “将频率添加到列表时” - 您正在将 DummyConfig 添加到列表中,但我们不知道那是什么。在循环的其余部分中,您不会在任何地方使用它。但此外,您在循环的每次迭代中都使用相同的数组 - 您永远不会创建新数组。
  • 我打错了那个。我会尝试制作新的数组。只是想想,这似乎有点笨拙。会有更好的解决方案吗?如果这很重要,我也会在其他人停止的地方接手这个。我已经破坏了很多现有代码,并且不得不修复很多。
  • 如果你想引用列表中几个不同的、独立的、独立的数组,你需要在循环的每次迭代中创建一个数组。我看不出有什么笨拙的地方。
  • 我并没有考虑在循环的每次迭代中做,而是在循环之外创建它们。更有意义。感谢您的 cmets。

标签: c# .net list


【解决方案1】:

您需要将 TestConfigFrequencies 变量的实例化移动到 for 循环中,以便每次都使用不同的对象。

for(i = 0; i < NumberofXmlValues; i++)
{
    TestConfig = new Configuration();
    Frequencies = new ushort [7];

我个人建议制作这些本地声明的变量而不是持久字段。该模式将帮助您避免将来出现此类错误。

for(i = 0; i < NumberofXmlValues; i++)
{
    /*check that the description, Mode, Deviation are valid*/
    ...
    try
    {
        var testConfig = new Config
        {
            Description = description
            ...
            Frequencies = new [] {xml_channel0, xml_channel1, ...}
               .Select(c => UInt16.Parse(c[i].InnerText))
               .ToArray()
        };
        Configurations.Add(testConfig);
    }
    ...

【讨论】:

  • 谢谢!第一个 sn-p 解决了我的问题。谢谢你。您对本地声明的变量与持久字段的评论,您可以扩展一下吗?比如为什么首选它,通用方法等等。C#是我在面向对象编程方面的第一次体验。我在学校只学过 C,我所学到的面向对象编程的一切都在我的职业生涯中。
  • @Billy:关于该原则的讨论和文章很多。例如。 hereherehere。此外,Code Complete recommends 将“初始化每个变量靠近它首次使用的位置。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 2016-02-01
  • 1970-01-01
相关资源
最近更新 更多