0

私はこれについて前後に議論しています。ハッシュテーブル(または辞書...どちらもこの目的に同じように機能するようです)が欲しいです

ItemNumber、Description、Quantityを持つクラスItemがあります。ハッシュテーブルまたはディクショナリのいずれかを使用したいクラスItemCollection(現在はItem配列を使用しています)があります。私のItemクラスでは、ItemNumberを使用して、アイテムa==アイテムbかどうかを比較します。

したがって、ハッシュテーブルのキーとしてItemNumberをItemCollectionまで移動する必要がありますか、それともそのままにしておく必要があります。アイテムに基づいてテーブルを生成するので、私の一部はそれを残したいと思っています。しかし、私の別の部分は、それが冗長でばかげていると思います。

私の最終目標は、このようなことを行うことで、出荷されたアイテムであるItemCollectionが別のItemCollection(注文)と等しいかどうかを確認することです。

foreach(var package in shipments)
    foreach(var item in package)
       shipOrder += item;

return mainOrder==shipOrder;

これが理にかなっていることを願っています。私の頭はまだ病気のため少し曇っています、それで私はもう少し明確にする必要があります私に知らせてください。

編集

さて、みんなの言うことを考えて試してみたところ、1つを除いてほとんどのテストに合格しましたが、その理由がわかりません。だから私は私が持っているものを投稿し、あなたたちが私の愚かな間違いを理解できるかどうかを確認します。

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
    }

....そして今、何らかの理由でそれが機能します... ItemのGetHashメソッドのコードで1つのことを変更し(ItemNumberからのハッシュで数量を排他的論理和するのを忘れました)、今ではそれらは...奇妙です。しかし、誰かに役立つかもしれないので、とにかく私のコードを投稿します。

4

2 に答える 2

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;
}
于 2012-12-06T21:06:00.443 に答える
0

をコレクションとして使用し、Item クラスでベース オブジェクトとメソッドをHashTable<T>オーバーライドできます。Equals()GetHashCode()

Equals メソッドがオーバーライドされたときに GetHashCode をオーバーライドすることが重要なのはなぜですか?

于 2012-12-06T19:09:02.247 に答える