0

我正在尝试创建一个简单的“库存”系统,该系统存储项目,键为项目名称,其余信息存储为值。但是,我很难弄清楚如何阅读这些信息。例如,如果我说一个包含 10 个项目的列表,并且我想从下面概述的关键“电视”中选择项目“类型”信息,我该怎么做?

电视 {大, 5, 3, false, dynamic, 0.8, 20}

Hashtable myItems = new Hashtable();    

protected virtual bool OnAttempt_AddItem(object args) {
            object[] arr = (object[])args;
            string ItemType = (string)arr[0];
            string ItemName = (string)arr[1];
            int ItemAmount = (arr.Length == 2) ? (int)arr[2] : 1;
            int ItemACanHave = (arr.Length == 3) ? (int)arr[3] : 1;
            bool ItemClear = (bool)arr[4];
            string ItemEffect = (string)arr[5];
            float ItemModifier = (float)arr[6];
            int ItemWeight = (int)arr[7];

            // enforce ability to have atleast 1 item of each type
            ItemACanHave = Mathf.Max(1, ItemACanHave);

            myItems[ItemName] = new object[] {ItemType, ItemAmount, ItemACanHave, ItemClear, ItemEffect, ItemModifier, ItemWeight };    

            return true;    
        }
4

2 回答 2

1

我建议您考虑库存清单中某一类型的多于一件的可能性,即两台或多台电视机,而不是只有一台。

使用基类和派生类:

public class InventoryItem
{
    public string ItemType { get; set; }
    public string ItemName { get; set; }
    public int ItemAmount { get; set; }
    public int ItemACanHave { get; set; }
    public bool ItemClear { get; set; }
    public string ItemEffect { get; set; }
    public float ItemModifier { get; set; }
    public int ItemWeight { get; set; }
}

public class Radio : InventoryItem
{
}

public class Television : InventoryItem
{
}

// TODO: add your derived classes

使用 aList<InventoryItem>来存储集合:

List<InventoryItem> InventoryItems = new List<InventoryItem>();

修改您的方法(不要忘记添加异常处理,因为有时您可能会得到与您在args对象中预期的不同的输入):

protected virtual bool OnAttempt_AddItem(object args)
{
    // TODO: handle unboxing exceptions, size of the array etc
    //
    try
    {
        object[] arr = (object[])args;
        switch (arr[0].ToString().ToLower())
        {
            // TODO: add other types (Radio etc)
            case "television":
                var tv = new Television();
                tv.ItemType = (string)arr[0];
                tv.ItemName = (string)arr[1];
                tv.ItemAmount = (arr.Length == 2) ? (int)arr[2] : 1;
                tv.ItemACanHave = (arr.Length == 3) ? (int)arr[3] : 1;
                tv.ItemClear = (bool)arr[4];
                tv.ItemEffect = (string)arr[5];
                tv.ItemModifier = (float)arr[6];
                tv.ItemWeight = (int)arr[7];

                // enforce ability to have atleast 1 item of each type
                tv.ItemACanHave = Math.Max(1, tv.ItemACanHave);
                InventoryItems.Add(tv);
                break;
            default:
                var genericItem = new InventoryItem();
                genericItem.ItemType = (string)arr[0];
                genericItem.ItemName = (string)arr[1];
                genericItem.ItemAmount = (arr.Length == 2) ? (int)arr[2] : 1;
                genericItem.ItemACanHave = (arr.Length == 3) ? (int)arr[3] : 1;
                genericItem.ItemClear = (bool)arr[4];
                genericItem.ItemEffect = (string)arr[5];
                genericItem.ItemModifier = (float)arr[6];
                genericItem.ItemWeight = (int)arr[7];

                // enforce ability to have atleast 1 item of each type
                genericItem.ItemACanHave = Math.Max(1, genericItem.ItemACanHave);
                InventoryItems.Add(genericItem);
                break;
            //handle other cases
        }
        return true;
    }
    catch (Exception ex)
    {
        // log the error
        return false;
    }
}

检索过滤后的项目,如下所示:

var largeTvType = inventory.InventoryItems.OfType<Television>()
    // filter by type (or other criteria)
    .Where(tv => tv.ItemType == "large")
    // select only the property your interested in (in the case below
    // it will be always "television" because that's part of the 
    // logic inside the OnAttempt_AddItem method's switch statement)
    .Select(tv => tv.ItemType);

尽管如此,正如 ChrisWue 在他的回答中所建议的那样,如果您知道您的库存清单会非常大,我建议您使用 a Dictionary<string, InventoryItem>string键是唯一的库存项目标识符。它会更快。

于 2013-05-13T08:38:37.713 回答
1

创建一个项目类来封装属性:

public class InventoryItem
{
    public string Name;
    public string Type;
    public int Amount;
    public int CanHave; // you should consider renaming this - it's very unclear what this could mean
    public bool Clear;
    public string Effect;
    public float Modifier;
    public int Weight;
}

然后您可以使用 Dictionary 来存储项目:

Dictionary<string, InventoryItem> inventory = new Dictionary<string, InventoryItem>();

inventory["television"] = new InventoryItem 
                                { 
                                     Name = "television", Type = "large", Amount = 5,
                                     CanHave = 3, Clear = false, Effect = "dynamic",
                                     Modifier = 0.8, Weight = 20
                                });

你可以像这样查找它:

Console.WriteLine("Type of television is: ", inventory["television"].Type);
于 2013-05-13T08:35:37.330 回答