如何获取ICollection<T>中项的索引

10
我有一份汽车清单。
ICollection<Cars> Cars

我也有一个单一的汽车对象,并且我知道它在ICollection中,我该如何获取汽车在列表中的索引/位置?我需要将它添加到字符串列表中。

以下是我的进展:

var index = cars.Where(b=> b.Id == car.id).Single().iWantTheIndex
stringList.Add(index)

有什么想法吗?

1
var index = cars.Select((b, i) => new { car = b, index = i }).Single(b => b.car.Id == car.id).index; - Blake Thingstad
1
@David 不,ICollection不一定有索引。 - Servy
1
@BlakeThingstad:聪明的做法,但这样做就是根据cars当前状态添加一个人为索引。系统不能保证同一“索引”在任何未来操作中都能匹配到同一对象。下一行代码可能会尝试基于该索引从cars中获取同一对象(很可能使用.Skip().First()之类的方法),但实际上得到的却是完全不同的对象。 - David
3
如果你要求实现类型为有序集合,需要所有项都具有有意义的索引,那么请确实要求使用一个接口作为契约,该接口要求这些内容(IList<T>),而不是没有要求的接口(ICollection<T>)。使用一个契约并没有明确规定所需的所有内容非常不好,只是希望任何使用该代码的人知道他们实际上应该提供特定类型的实现是不可取的。 - Servy
1
索引通常是一个数字,那么将其添加到字符串列表中,您的意思是什么? - CSharpie
显示剩余5条评论
2个回答

21
如果你想使用一个索引集合,那么应该使用 IList<T> 而不是 ICollection<T>ICollection<T> 是可以枚举、添加和移除项目以及获取计数的内容,仅此而已。 IList<T> 是一种有指定顺序的集合,可以根据它们在列表中的位置来访问集合项。
由于 ICollection<T> 不一定代表有序集合,因此无法获得项目的有意义“索引”。 项目不一定有位置。

1
这将给你当前迭代的索引:
var index = cars.Select((c, i) => new{ Index = i, Car = c })
                .Where(item => item.Car.Id == car.id)
                .Single()
                .Index;

stringList.Add(index);

请注意,下一个迭代可能有不同的顺序(取决于您的ICollection<>的实际实现),并且可能导致完全不同的索引,因此请注意您使用此索引的内容。

4
虽然这个索引没有提供任何有价值的内容,但是集合并没有被排序。下一次枚举可能会有完全不同的索引。 - Servy
1
@Servy 你说得对,下一次调用这个函数时,根据接口背后的实际实现,你可能会得到一个不同的索引。但是,我不能说那辆车的当前索引是否有任何价值。我只能说这是一种获取它的方法。 - nvoigt
2
但是你并没有当前值的索引。你只有索引曾经在一个永远无法再次访问的序列中的值。你实际上并没有集合中项目的索引。 - Servy
@Servy 你是对的,current 不是一个恰当的词汇选择。Last 更为准确。 - nvoigt
1
@nvoigt,您能否在答案中添加一些评论,以便将来对其他人更有价值? - Dr Rob Lang
1
@DrRobLang 完成了 :) - nvoigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接