遍历SortedDictionary键触发KeyNotFoundException,元素超2个才报错
解决SortedDictionary遍历键时抛出KeyNotFoundException的问题
你的问题根源在于Product_for_sale类的IComparable实现完全错误,SortedDictionary依赖正确的比较逻辑维护内部有序结构和键查找功能,你的CompareTo方法只返回0或1,从未返回负数,这会导致集合内部的排序与索引逻辑彻底混乱,当元素数量超过2个时,就会出现键找不到的异常。
问题分析
SortedDictionary要求比较方法必须满足全序关系:
- 当A < B时,A.CompareTo(B)返回负数
- 当A == B时,返回0
- 当A > B时,返回正数
而你的实现中:
- 仅当两个对象name相等时返回0,其余情况一律返回1
- 这意味着比较A和B(name不同)时,A.CompareTo(B)=1,B.CompareTo(A)也=1,完全违背比较的对称性,导致SortedDictionary无法正确维护键的顺序与索引,最终遍历键集合时,用当前key查找对应值会失败。
修复方案
修改Product_for_sale的CompareTo和equals方法,基于name的字符串比较结果返回正确数值:
// 修改后的equals方法 int Product_for_sale::equals(Product_for_sale^ pfs) { return this->name->CompareTo(pfs->getName()); } // 修改后的CompareTo方法 int Product_for_sale::CompareTo(Object^ obj){ if (obj->GetType() == Product_for_sale::typeid) { Product_for_sale^ product = dynamic_cast<Product_for_sale^>(obj); return equals(product); } // 非同类对象应抛出异常,符合IComparable规范 throw gcnew ArgumentException("对象不是Product_for_sale类型"); }
额外优化
遍历SortedDictionary时,直接遍历KeyValuePair可避免二次查找(products[key]是一次O(log n)的查找),同时彻底规避键查找异常,代码更高效:
void Score:: setProductsLabel() { int y = 50; productLabels.Clear(); // 直接遍历键值对,无需二次查找 for each (KeyValuePair<Product_for_sale^, int> kvp in products) { Product_for_sale^ key = kvp.Key; int count = kvp.Value; String^ product_by_score = ""; System::Windows::Forms::Label^ info = (gcnew System::Windows::Forms::Label()); if (count > 0) { product_by_score = key->getName() + " | " + count + " | " + key->getFullPrice() * count + "\n"; info->BackColor = System::Drawing::Color::Red; } else { info->BackColor = System::Drawing::Color::PaleGreen; product_by_score = key->getName() + " | " + "СОБРАНО" + " | " + key->getFullPrice() * count + "\n"; } info->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 10.00F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(204))); info->AutoSize = true; info->Location = System::Drawing::Point(10, y); info->Name = L"label4"; info->Size = System::Drawing::Size(100, 25); info->TabIndex = 2; info->Text = product_by_score; productLabels.Add(key,info ); y += 30; } }
验证点
修复后测试不同元素数量的场景,SortedDictionary的内部结构会正确维护,遍历与查找都不会再抛出KeyNotFoundException。
内容的提问来源于stack exchange,提问作者RedToni
相关产品推荐
相关产品推荐

