如何使用C#中的索引从IEnumerable集合中获取项目?

时间:2018-11-02 14:39:47

标签: c# ienumerable

我有IEnumerable的{​​{1}}列表和索引。现在我想根据索引获取customerList的项目。

例如,如果IEnumerable,它应该提供IEnumerable的第三项。

请指导。

index = 3

4 个答案:

答案 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可能是您的用例的更好抽象。