我有IEnumerable
的{{1}}列表和索引。现在我想根据索引获取customerList
的项目。
例如,如果IEnumerable
,它应该提供IEnumerable的第三项。
请指导。
index = 3
答案 0 :(得分:6)
例如,如果index = 3,则应向我提供 IEnumerable
您知道.NET中的索引是从零开始的吗?但是,您可以使用ElementAt
:
Customer c = customerList.ElementAt(currentIndex); // 4th
如果没有足够的项目,请使用ElementAtOrDefault
阻止异常,然后您会得到null
:
Customer c = customerList.ElementAtOrDefault(currentIndex); // 4th or null
这些方法以使用IList<T>
indexer的方式进行了优化。因此,在您的示例中,实际上有一个实现该接口的Customer[]
,因此它将使用索引器。
如果该序列未未实现IList<T>
,将枚举该序列以找到该索引处的项目。
答案 1 :(得分:2)
不要使用IEnumerable。使用IList代替:
IList<Customer> customerList = new Customer[]
{
new Customer { Name = "test1", Id = 999 },
new Customer { Name = "test2", Id = 915 },
new Customer { Name = "test8", Id = 986 },
new Customer { Name = "test9", Id = 988 },
new Customer { Name = "test4", Id = 997 },
new Customer { Name = "test5", Id = 920 },
};
对于IEnumerable,唯一的选择是使用ElementAt()扩展方法。
IEnumerable<T>
仅保证可以枚举集合。它对访问元素没有其他承诺。 ElementAt允许通过枚举一次访问一个特定元素来访问特定元素,直到达到所需元素为止。那可能很贵。
幸运的是,ElementAt checks to see whether the argument is an IList会使用基于索引的访问。
但这并不意味着您应该使用IEnumerable<T>
。它将使不知道变量背后的实际实例是什么的维护者(包括您)感到困惑。如果不是 IList被分配给该变量,也会导致性能问题
答案 2 :(得分:1)
这可以使用ElementAt
方法来实现。
如果您的IEnumerable 不是具体化的集合,而是已生成的序列,则多次调用ElementAt
方法将导致该序列被多次生成。这通常是不希望的,因为它不必要地消耗资源。
上面的某些答案建议使用IList
而不是IEnumerable
。是的,绝对可以减少按索引访问的麻烦,但是使用IList
有一个讨厌的副作用,它使集合变得易变。我会改用IReadOnlyList
。
IReadOnlyList<Customer> customerList = new Customer[]
{
new Customer { Name = "test1", Id = 999 },
new Customer { Name = "test2", Id = 915 },
new Customer { Name = "test8", Id = 986 },
new Customer { Name = "test9", Id = 988 },
new Customer { Name = "test4", Id = 997 },
new Customer { Name = "test5", Id = 920 },
};
int currentIndex = 3; //want to get object Name = "test8", Id = 986
var result = customerList[currentIndex];
customerList.Add(new Customer()); // doesn't compile
customerList[currentIndex] = new Customer(); // doesn't compile
答案 3 :(得分:0)
IEnumerable是一种“流式”数据类型,因此应将其视为流而不是数组。
var yourCustomer = customerList.Skip(2).First()
但是,如果您希望使用类似语法的数组,则IList可能是您的用例的更好抽象。