我正在就这个来回辩论。我想要一个Hashtable(或字典......两者似乎都为此目的做得好)
我有一个具有ItemNumber,Description和Quantity的类Item。我有一个ItemCollection类(当前使用Item数组),我想使用哈希表或字典。在我的Item类中,我使用ItemNumber来比较项a == item b。
所以我应该将ItemNumber移动到ItemCollection作为我的哈希表的键,或者我应该离开它。部分我想离开它,因为我根据Item生成了一个表。但是我的另一部分认为这是多余和愚蠢的。
我的最终目标是通过执行类似的操作来查看作为发货项目的ItemCollection是否等于另一个ItemCollection(订单)。
foreach(var package in shipments)
foreach(var item in package)
shipOrder += item;
return mainOrder==shipOrder;
我希望这是有道理的。我的头仍然有点生病,所以我需要澄清一些,请告诉我。
修改 的
好的,所以我想到了每个人都说了什么,并尝试过,大多数测试都通过了,除了一个,我无法弄清楚为什么。所以我会发布我所拥有的内容,看看你们是否可以找出我的愚蠢错误。public class Item
{
public Item(object[] array)
{
ItemNumber = array[0].ToString();
Description = array[1].ToString();
Quantity = (int)array[2];
}
public Item(string item, string desc, int qty)
{
ItemNumber = item;
Description = desc;
Quantity = qty;
}
/// <summary>
/// </summary>
public string ItemNumber;
public string Description;
public int Quantity;
public override bool Equals(object obj)
{
//return compareTwoItems(this, (Item)obj);
return this.GetHashCode() == obj.GetHashCode();
}
public static bool operator ==(Item ic1, Item ic2)
{
return compareTwoItems(ic1, ic2);
}
public static bool operator !=(Item ic1, Item ic2)
{
return !compareTwoItems(ic1, ic2);
}
private static bool compareTwoItems(Item ic1, Item ic2)
{
return (ic1.ItemNumber == ic2.ItemNumber)
&& (ic1.Quantity == ic2.Quantity);
}
public override int GetHashCode()
{
return ItemNumber.GetHashCode() ^ Quantity;
}
}
public class ItemCollection : System.Collections.Generic.SortedDictionary<string, Item>
{
public ItemCollection()
{
}
public void AddItem(Item i)
{
this.Add(i.ItemNumber, i);
}
public string TrackNumber = "";
/// <summary>
/// Check to see if the Two ItemCollections have the same Quantity of items. If not it may be that the order was not completed
/// </summary>
/// <param name="obj">the sales order items</param>
/// <returns>True if the quantity of the two collections are the same.</returns>
/// <exception cref="ArgumentException">If the collections have different counts, or if ItemNumbers differ in one of the elements</exception>
public override bool Equals(object obj)
{
return this.GetHashCode() == ((ItemCollection)obj).GetHashCode();
}
public override int GetHashCode()
{
int hash = 0;
foreach (var item in this.Values)
hash ^= item.GetHashCode();
return hash;
}
/// <summary>
/// Check to see if the Two ItemCollections have the same Quantity of items. If not it may be that the order was not completed
/// </summary>
/// <param name="ic1">the sales order items</param>
/// <param name="ic2">the shipping ticket items</param>
/// <returns>True if the quantity of the two collections are the same.</returns>
/// <exception cref="ArgumentException">If the collections have different counts, or if ItemNumbers differ in one of the elements</exception>
public static bool operator ==(ItemCollection ic1, ItemCollection ic2)
{
return ic1.Equals(ic2);
}
public static bool operator !=(ItemCollection ic1, ItemCollection ic2)
{
return !ic1.Equals(ic2);
}
}
单元测试
[TestMethod, TestCategory("ItemColl")]
public void ItemCollectionPassTest()
{
MSSqlDatabase db = new MSSqlDatabase();
ItemCollection salesOrder = db.GetItemsCollectionFromSalesOrder(4231);
ItemCollection items = db.GetItemsCollectionFromSalesOrder(4231);
Assert.AreEqual(salesOrder, items); //passes
Assert.IsTrue(salesOrder == items); //passes
}
[TestMethod, TestCategory("ItemColl")]
public void ItemCollectionDifferentQuantity()
{
MSSqlDatabase db = new MSSqlDatabase();
ItemCollection salesOrder1 = db.GetItemsCollectionFromSalesOrder(4231);
ItemCollection salesOrder2 = db.GetItemsCollectionFromSalesOrder(4232);
Assert.AreNotEqual(salesOrder1, salesOrder2); //passes
Assert.IsTrue(salesOrder1 != salesOrder2); //passes
ItemCollection[] items = db.GetItemsCollectionFromShipping(4231);
ItemCollection test = items[0];
Assert.AreNotEqual(salesOrder1, test); //Fails
CollectionAssert.AreNotEqual(salesOrder1, items[0]); // passes
}
....现在由于某种原因它可以工作......我在我的代码中改变了一件物品中的GetHash方法(忘了用ItemNumber中的哈希来计算数量)现在他们通过......奇怪的。但我会发布我的代码,因为它可能有助于某人。
答案 0 :(得分:1)
我同意scarle88,我认为您的ItemCollection
应该延伸Dictionary
或Hashtable
。字典对于每个项目都需要一个唯一的密钥,您可以使用该项目编号(如果您的要求是每个项目都是唯一的)。
像这样:
public class Item {
public string ItemNumber { get; set; }
public string Description { get; set; }
public string Quantity { get; set; }
public override bool Equals(Object o) {
// Implement your Equals here
}
public override int GetHashCode() {
// Implement your hash code method here
}
}
public class ItemCollection : Dictionary<string, Item> {
public override bool Equals(Object o) {
// Implement your collection's Equals method here
}
}
我不确定您对比较收藏品的要求是什么。但是如果你只关心两个集合都有相同的项目,你可以像这样实现ItemCollection.Equals
:
public override bool Equals(Object o) {
if (o == null)
return false;
if (!(o is ItemCollection))
return false;
var other = o as ItemCollection;
// check the 'this' collection
foreach (var item in this.Keys) {
if (item != null && !other.ContainsKey(item.ItemNumber))
return false;
// check the 'other' collection
foreach (var item in other.Keys) {
if (item != null && !this.ContainsKey(item.ItemNumber))
return false;
return true;
}
答案 1 :(得分:0)
您可以使用HashTable<T>
作为集合,并在Item类中覆盖基础对象Equals()
和GetHashCode()
方法。
Why is it important to override GetHashCode when Equals method is overridden?