根据标题... list.First()、list.ElementAt(0) 和 list[0] 之间有任何实际差异吗?
.First()
方法在源列表中不包含任何元素时会抛出异常。参见Remarks部分。为了避免这种情况,应该使用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
list [0]
和list.ElementAt(0)
将抛出ArgumentIndexOutOfRangeException
,而list.First()
将抛出InvalidOperationException
。First()
和ElementAt(0)
都与任何序列兼容——任何实现IEnumerable
的方式。这很有用,因为它意味着您可以将变量与不同的IEnumerable
实现交换,而无需更改任何代码。相比之下,索引器仅适用于直接实现该功能的列表和其他结构。ElementAt
有合理的机会成为O(n),而不是O(1),而索引器通常被认为速度快。没有区别。它们都执行相同的操作,返回列表中的第一个项目。
编辑:我想我不应该说没有区别。ElementAt()和First()都有一些错误处理,检查null和超出范围的索引,但这不应该真正有什么影响。