如何使用 C# 中的索引从 IEnumerable 集合中获取项目?
How to get item from IEnumerable collection using its index in C#?
我有 IEnumerable
个 customerList
列表和索引。现在我想根据索引获取 IEnumerable
的项目。
例如,如果 index = 3
,它应该为我提供 IEnumerable 的第 3 项。
请指导。
IEnumerable<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
For example, if index = 3, it should provide me 3rd item of the
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>
,它将被枚举以在该索引处找到项目。
如果您想要基于索引的访问,请不要 使用 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 的东西曾经分配给该变量
,它也会导致性能问题
IEnumerable 是一种 'streaming' 数据类型,因此可以将其视为流而不是数组。
var yourCustomer = customerList.Skip(2).First()
但是,如果您想要更像数组的语法,IList 可能是您用例的更好抽象。
这可以使用 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
我有 IEnumerable
个 customerList
列表和索引。现在我想根据索引获取 IEnumerable
的项目。
例如,如果 index = 3
,它应该为我提供 IEnumerable 的第 3 项。
请指导。
IEnumerable<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
For example, if index = 3, it should provide me 3rd item of the 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>
,它将被枚举以在该索引处找到项目。
如果您想要基于索引的访问,请不要 使用 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 的东西曾经分配给该变量
IEnumerable 是一种 'streaming' 数据类型,因此可以将其视为流而不是数组。
var yourCustomer = customerList.Skip(2).First()
但是,如果您想要更像数组的语法,IList 可能是您用例的更好抽象。
这可以使用 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