2012-12-06 58 views
0

我對此進行了辯論。我想要一個Hashtable(或字典......兩者似乎同樣適用於此目的)如果我的散列表值包含密鑰

我有一個具有ItemNumber,Description和Quantity的類Item。我有一個類ItemCollection(它當前使用一個Item數組),我想要使用散列表或字典。在我的Item類中,我使用ItemNumber比較項目a ==項目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的哈希),現在他們通過......怪異的。但我會發布我的代碼,因爲它可能會幫助某人。

回答

1

我scarle88同意,我認爲你應該ItemCollection延長DictionaryHashtable。字典將需要每個項目的唯一密鑰,並且您可以使用該項目編號(如果您的要求是每個項目都是唯一的)。

像這樣:

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; 
} 
+0

非常感謝你的例子。讓我告訴你我有什麼,因爲一個奇怪的原因,我的單元測試失敗 –

+0

我很高興它開始工作。我不能告訴你爲什麼它以前失敗了,看起來這取決於你從數據庫中獲得的數據。 –

+0

是啊,它說像預期的東西是ItemCollection和Found ItemCollection ..我開始瘋了,因爲它不工作。現在它是。 –

0

您可以使用HashTable<T>作爲您的收藏,並在您的Item類中覆蓋基礎對象Equals()GetHashCode()方法。

Why is it important to override GetHashCode when Equals method is overridden?

+0

我已經做到了,但關於我的項目數是不是一個數字的說明它是一個字符串。 (我不喜歡它,但它超出了我的控制範圍)應該將字符串變成一個字節數組和字節數組嗎? –

+1

在您的Item類的GetHashCode覆蓋中,您可以簡單地返回ItemNumber的哈希碼,例如:return _itemNumber。的GetHashCode(); –

+0

不是一個混蛋,但你的回答並不顯示我是否應該在Item Item中保留ItemNumber。其他部分是有意義的,並且恰好回答了我的其他問題 –

相關問題