【发布时间】:2011-05-29 01:41:42
【问题描述】:
根据标题... list.First()、list.ElementAt(0) 和 list[0] 之间有什么真正的区别吗?
【问题讨论】:
根据标题... list.First()、list.ElementAt(0) 和 list[0] 之间有什么真正的区别吗?
【问题讨论】:
.First() 将在源列表不包含任何元素时引发异常。 See the Remarks section。为避免这种情况,请使用FirstOrDefault()。
.ElementAt(0) 如果索引大于或等于列表中的元素数,将抛出异常。为避免这种情况,请使用ElementAtOrDefault(0)。如果您使用的是 LINQ To SQL,则无法将其转换为 sql,而 .First() 可以转换为 TOP 1。
如果索引大于或等于列表中元素的数量,索引器也会抛出异常。它不提供OrDefault 选项来避免这种情况,并且不能将其转换为用于 LINQ To SQL 的 sql。编辑:我忘了提到一个简单的显而易见的事情,即如果您的对象是 IEnumerable,则不能使用这样的索引器。如果你的对象是一个实际的 List,那么你就可以了。
【讨论】:
也许是一个老问题,但存在性能差异。
下面的代码:
var lst = new List<int>();
for (int i = 0; i < 1500; i++)
{
lst.Add(i);
}
int temp;
Stopwatch sw1 = new Stopwatch();
sw1.Start();
for (int i = 0; i < 100; i++)
{
temp = lst[0];
}
sw1.Stop();
Stopwatch sw2 = new Stopwatch();
sw2.Start();
for (int i = 0; i < 100; i++)
{
temp = lst.First();
}
sw2.Stop();
Stopwatch sw3 = new Stopwatch();
sw3.Start();
for (int i = 0; i < 100; i++)
{
temp = lst.ElementAt(0);
}
sw3.Stop();
您将获得以下时间(以刻度为单位):
lst[0]
sw1.ElapsedTicks
253
lst.First()
sw2.ElapsedTicks
438
lst.ElementAt(0)
sw3.ElapsedTicks
915
【讨论】:
在“有效”情况下(即,当列表至少有一个元素时),它们与 APshredder 指出的相同。如果没有元素,那么list[0] 和list.ElementAt(0 将抛出一个ArgumentIndexOutOfRangeException,而list.First() 将抛出一个InvalidOperationException。
【讨论】:
在这些选项之间进行选择的另一个考虑因素是 First() 和 ElementAt(0) 都与 any 序列兼容——IEnumerable 的任何实现。 (这可能很有用,因为这意味着您可以用 IEnumerable 的不同实现替换您的变量,而无需更改任何代码。)相比之下,索引器仅适用于直接实现该功能的列表和其他结构。
相反,使用索引器可能是确保(在编译时)获得优化性能的好方法,因为ElementAt 有合理的机会是 O(n) 而不是 O(1),而索引器是通常被认为很快。
【讨论】:
不,完全没有区别。他们都做同样的事情,返回列表中的第一项。
编辑:我想我不应该说没有区别。 ElementAt() 和 First() 都有一些它们所做的错误处理,检查空值和超出范围的索引,但它不应该真的很明显。
【讨论】: