C# c如何从数组中检索对象作为值
我正在尝试创建一个简单的“库存”系统,该系统存储项,键是项名称,其余信息存储为值。然而,我很难弄清楚如何阅读这些信息。例如,如果我有一个包含10个项目的列表,并且我想从下面概述的“电视”键中选择项目“类型”信息,我该怎么做 电视{大,5,3,假,动态,0.8,20}C# c如何从数组中检索对象作为值,c#,arrays,object,C#,Arrays,Object,我正在尝试创建一个简单的“库存”系统,该系统存储项,键是项名称,其余信息存储为值。然而,我很难弄清楚如何阅读这些信息。例如,如果我有一个包含10个项目的列表,并且我想从下面概述的“电视”键中选择项目“类型”信息,我该怎么做 电视{大,5,3,假,动态,0.8,20} 创建一个item类来封装属性: public class InventoryItem { public string Name; public string Type; public int Amount;
创建一个item类来封装属性:
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
});
我建议你考虑一个清单中某一类型的不止一个项目的可能性,即两个或多个电视机,而不是只有一个。 使用基类和派生类:
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> InventoryItems = new List<InventoryItem>();
检索筛选的项目,如下所示:
Console.WriteLine("Type of television is: ", inventory["television"].Type);
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);
不过,正如克里斯伍在回答中所建议的那样,如果你知道你的库存清单将非常大,我建议你使用字典,字符串键是唯一的库存项目标识符。它会更快。是否有任何原因使您仍然使用非通用哈希表集合而不是字典?听起来您应该创建一个Item类来封装所有这些值。顺便说一句,我没有使用HashTable,但是使用自定义实体类有什么问题吗?我对C及其数组类型相当陌生。如果有更好的方法,如果有人能介绍给我,我将不胜感激。你熟悉OOP吗?为您的项目定义类,并使用通用字典创建结构良好且速度足够快的数据实体。您忘记了清单中的键。AddJust好奇-对类中的自动属性使用字段有什么好处吗?@Tommi:这取决于它的用途。您随时可以稍后重构它。尝试此方法时,我会收到一个错误-错误CS1525:意外的符号[',需要标识符“这是因为我上面提到的打字错误。索引器不应用逗号分隔,请将库存。[TV]替换为库存[TV]我能解释一下这个方法和@ChrisWue之间的区别吗?主要的区别是使用列表而不是字典。我认为如果您想按键获取项,这不是一个好主意。字典查找的复杂性是O1,而LINQ查询在普通情况下是打开的。此外,如果您愿意,您仍然可以使用字典的LINQ On.Values成员“需要。对于您想要实现的目标,有两种观点。我相信我们都根据自己的一些假设为您提供了一些示例。我们都使用了一个类来处理强类型对象。他使用字典集合,我使用的是列表。”。
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);