.NET版本低于4时,如何从嵌套Dictionary中正确提取数据?
嘿,我来帮你搞定这个嵌套字典的问题!首先得先修正你添加数据时的一个隐藏bug,然后再解决取值的问题,完全适配你低于.NET 4的版本限制。
首先,你当前的while循环里有个大问题:每次读取数据都会直接给dateDict添加同一个DateTime键,如果有相同日期的多条数据,这里会直接抛出ArgumentException(提示键已存在)。正确的添加逻辑应该是先检查日期是否已经在字典里,不存在再创建内层字典,然后再把事件的name和guid加进去:
while (reader.Read()) { DateTime date = DateTime.Parse(reader["Event_Date"].ToString()); string name = reader["Event_Name"].ToString(); string guid = reader["Event_GUID"].ToString(); // 先检查当前日期是否已经在外层字典中 if (!dateDict.ContainsKey(date)) { dateDict.Add(date, new Dictionary<string, string>()); } // 把当前事件的name和guid添加到对应日期的内层字典里 dateDict[date].Add(name, guid); }
接下来解决你最头疼的取值问题:你写的dateDict[keyVar[]]是明显的语法错误,而且你得明确:外层字典的每个DateTime键对应的是一整个内层字典(里面可能有多个name-guid的键值对)。结合你的eventDateBoxes和eventTextBoxes数组,分两种常见场景处理:
场景1:每个日期对应一个文本框(比如显示该日期下的第一个事件)
如果你的数组长度和外层字典的日期数量一致,且每个日期只需要展示一组事件信息,可以用foreach遍历外层字典(.NET 3.5及以下都支持),同时用索引跟踪数组的位置:
int index = 0; foreach (var dateEntry in dateDict) { // 给DateTimePicker设置日期 eventDateBoxes[index].Value = dateEntry.Key; // 取内层字典的第一个键值对(如果需要其他的可以调整逻辑) // 注意:如果内层字典为空会报错,建议先判断是否有数据 if (dateEntry.Value.Count > 0) { var firstEvent = dateEntry.Value.First(); eventTextBoxes[index].Text = $"事件名称:{firstEvent.Key},GUID:{firstEvent.Value}"; } index++; // 加个判断防止数组越界:如果索引超过数组长度就停止 if (index >= eventDateBoxes.Length) break; }
场景2:每个日期的所有事件对应多个文本框
如果一个日期下有多个事件,需要对应多个文本框,那就嵌套遍历内层字典:
int boxIndex = 0; foreach (var dateEntry in dateDict) { // 先给当前日期对应的DateTimePicker赋值 eventDateBoxes[boxIndex].Value = dateEntry.Key; // 遍历当前日期下的所有事件 foreach (var eventEntry in dateEntry.Value) { // 防止数组越界,超出长度就停止 if (boxIndex >= eventTextBoxes.Length) break; eventTextBoxes[boxIndex].Text = $"事件:{eventEntry.Key},GUID:{eventEntry.Value}"; boxIndex++; } }
额外建议:低版本.NET的更优替代方案(不用元组/自定义类也能更清晰)
虽然你说暂时不想用自定义类,但其实自定义一个简单的类来存事件信息真的很简单,而且代码可读性会高很多,完全兼容低版本.NET:
public class EventInfo { public DateTime EventDate { get; set; } public string EventName { get; set; } public string EventGuid { get; set; } }
然后用List<EventInfo>代替嵌套字典,添加数据和取值都会更直观:
List<EventInfo> eventList = new List<EventInfo>(); while (reader.Read()) { eventList.Add(new EventInfo { EventDate = DateTime.Parse(reader["Event_Date"].ToString()), EventName = reader["Event_Name"].ToString(), EventGuid = reader["Event_GUID"].ToString() }); } // 取值的时候直接遍历List就行 for (int i = 0; i < eventList.Count; i++) { eventDateBoxes[i].Value = eventList[i].EventDate; eventTextBoxes[i].Text = $"名称:{eventList[i].EventName},GUID:{eventList[i].EventGuid}"; }
这种方式比嵌套字典更不容易出错,后续维护也更方便。
内容的提问来源于stack exchange,提问作者Ben R
相关产品推荐
相关产品推荐

