Can't add to a list within a class object
首先,如果这是一个愚蠢的问题,我会道歉的。自从vb6以来,我一直在使用c_16个小时,没有编程任何东西。我只是想破解一个个人使用的小程序,它从旧的Access数据库中读取数据,并在Excel中输出格式化的报告。我为混乱/低效的代码道歉。
概述:我有两个类类型,"区域"和"设备"。每个"区域"中都有一个设备列表。主程序有一个区域列表。每个数据库中都有不同数量的"区域",并且每个"区域"都有不同数量的设备分配给它。我需要按顺序分析区域列表和每个区域上的设备。我从结构和数组开始,人们普遍认为这两种方法都是不好的,而且我也没有太多运气,所以我搬到了列表和类,一切都很顺利。
我可以从数据库中提取所有"区域",将它们添加到列表中,为它们分配标签和ID。问题是,当我从数据库中读取"设备"时,无法将它们添加到区域内的列表中。
这是我得到的错误:"对象引用没有设置为对象的实例。"我收集到的信息表示对象为空?
相关代码如下:
设备类别:
1 2 3 4 5 6 7 8 9 10 11 12 | public class Device { public string Label; public string Address; public string Type; public Device(string Label, string Address, string Type) { this.Address = Address; this.Label = Label; this.Type = Type; } } |
区域类别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Zone { public string Label; public short ID; public List<Device> Devices; public Zone(string Label, short ID) { this.Label = Label; this.ID = ID; // ADDED AS PER SUGGESTIONS BELOW this.Devices = new List<Device>(); } // Added this to see if it would work, it would not. public void AddDevice(string Label, string Address, string Type) { Devices.Add(new Device(Label, Address, Type)); } } |
初始化和填充区域列表(单击按钮)(成功完成)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | List<Classes.Zone> Zones = new List<Classes.Zone>(); dbZoneReader = myZoneSelect.ExecuteReader(); while (dbZoneReader.Read()) { Classes.dbItem dbRow = new Classes.dbItem(); dbRow.Address = Convert.ToInt16(dbZoneReader["DeviceAddress"].ToString()); dbRow.DeviceType = Convert.ToInt16(dbZoneReader["DeviceType"].ToString()); dbRow.Label = dbZoneReader["DeviceLabel"].ToString(); if (dbRow.Label !="" && dbRow.Address > 0) { Zones.Add(new Classes.Zone(dbRow.Label,dbRow.Address)); } } |
将设备添加到各自的区域:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | while (dbReader.Read()) { Classes.dbItem dbRow = new Classes.dbItem(); string tempZones; // Acquire/convert device information dbRow.Node = Convert.ToInt16(dbReader["NodeAddress"].ToString()); dbRow.Loop = Convert.ToInt16(dbReader["LoopSelection"].ToString()); dbRow.Address = Convert.ToInt16(dbReader["DeviceAddress"].ToString()); dbRow.TypeID = Convert.ToInt16(dbReader["TypeID"].ToString()); dbRow.FlashScanID = Convert.ToInt16(dbReader["FlashScanID"].ToString()); dbRow.DeviceType = Convert.ToInt16(dbReader["DeviceType"].ToString()); dbRow.Label = dbReader["DeviceLabel"].ToString(); // Find"proper" zone ID (some zones have multiple IDs, only one is relevant) tempZones = dbReader["DevicePointMappingList"].ToString(); tempZones = tempZones.Replace("Z",""); var elements = tempZones.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); if (elements.Length >= 2) { ZoneCheck z = new ZoneCheck(); foreach (string items in elements) { if (z.Check(items)) { dbRow.Zone = Convert.ToInt16(items); } } } else { if (elements.Length == 1) { dbRow.Zone = Convert.ToInt16(elements[0]); } else { dbRow.Zone = 0; } } // Only add devices that aren't assigned to zone 0, which is non-existent if (dbRow.Zone > 0) { // Add new device to zone's device list [THIS IS WHERE IT FAILS] Zones.Find(z => z.ID == dbRow.Zone).Devices.Add(new Classes.Device("Test","test","Test")); } } |
我已经检查过了,发现了它到底在哪里失败,这是它试图添加设备的最后一行。搜索这里和谷歌,让我相信我需要初始化对象列表…我相信我已经做到了?我尝试在区域类构造函数中初始化它,并且在添加区域时(这也是它现在设置的)。
我已经确认区域对象存在,并且该区域对象中的检测器列表不是空的。有点困惑,觉得我在做一些我不该做的事情,只是不知道更好,或者我错过了一些非常明显的事情。
问题出在你的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Zone { public string Label; public short ID; public List<Device> Devices; public Zone(string Label, short ID) { this.Label = Label; this.ID = ID; this.Devices = new List<Device>(); } // Added this to see if it would work, it would not. public void AddDevice(string Label, string Address, string Type) { Devices.Add(new Device(Label, Address, Type)); } } |
原因是,当您编写
用一个简单的对象来思考同一个问题可能有助于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Foo { public string bar; // bar isn't an actual instance of an object, it's just a spot that can hold a string public void ManipulateBarWithRuntimeError() { bar.Substring(0, 1); //"bar" isn't actually set to anything, so how can we take a substring of it? This is going to fail at runtime. } public void ManipulateBarWithoutRuntimeError() { bar ="Hello, world!"; bar.Substring(0, 1); // bar is actually set to a string object containing some text, so now the Substring method will succeed } } |
还可以在getter中初始化列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class Zone { public string Label; public short ID; private List<Device> _devices; public List<Device> Devices { get { return this._devices ?? (this._devices = new List<Device>()); } } public Zone(string Label, short ID) { this.Label = Label; this.ID = ID; } // Added this to see if it would work, it would not. public void AddDevice(string Label, string Address, string Type) { Devices.Add(new Device(Label, Address, Type)); } } |
我认为问题出在你的
这是我对您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Zone { public string Label; public short ID; public List<Device> Devices; public Zone(string Label, short ID) { this.Label = Label; this.ID = ID; this.Devices = new List<Device>(); } // Added this to see if it would work, it would not. public void AddDevice(string Label, string Address, string Type) { Devices.Add(new Device(Label, Address, Type)); } } |
这是我对你们班唯一的改变;
1 |
现在它可能工作了…