c#如何从数组中检索对象作为值

时间:2013-05-13 08:24:33

标签: c# arrays object

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

  

电视{大,5,3,假,动态,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;    
        }

2 个答案:

答案 0 :(得分: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<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);

答案 1 :(得分: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

使用List<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在答案中建议的那样,如果您知道您的广告资源列表会非常大,我建议您使用Dictionary<string, InventoryItem>string密钥是唯一的广告资源标识符。它会更快。