List.AddRange与LINQ.ToList()相比有哪些优势?

6

今天我正在学习MVC4的教程,看到用户使用不同于我所熟悉的方式实现了一个选择器。他的代码是:

var GenreLst = new List<string>(); 

var GenreQry = from d in db.Movies 
               orderby d.Genre 
               select d.Genre; 
GenreLst.AddRange(GenreQry.Distinct()); 
ViewBag.movieGenre = new SelectList(GenreLst); 

我看了一下,按照我的方式重写如下:

var genres = db.Movies
            .OrderBy(m => m.Genre)
            .Select(m => m.Genre)
            .Distinct()
            .ToList();

ViewBag.MovieGenre = new SelectList(genres);

他的GenreList变量没有在其他地方使用,所以我把它删掉了。我的主要问题是他如何使用AddRange。 AddRange比ToList更好吗?

谢谢阅读!


1
好的,AddRange 允许您将项目添加到现有列表中。 ToList 则不行。 - Brian Rasmussen
@TimSchmelter的AddRange方法很聪明,它会根据添加到范围内的项数自动增加缓冲区的大小。虽然您仍将分配默认大小为10的缓冲区并且不使用它,但是您不会重新分配大量的缓冲区。 - Servy
@Servy:抱歉,我刚刚删除了我的评论。如果查询未执行,则无法查看数字,只能将其转换为“ICollection <T>”进行查看。否则,必须执行并枚举它。在这种情况下,大小是未知的,列表可能是所需大小的两倍大。 - Tim Schmelter
@TimSchmelter 如果它实际上不是一个 IList,那么构造函数也不会知道大小,所以它的工作方式是一样的。显然,程序员并没有手动输入大小,因此在编译时他不知道[大致]大小将是多少。 - Servy
@Sery:是的,这不太常见,但我想说的是,可能存在差异。var range=Enumerable.Range(1, 10000000);List<int> list=range.ToList()实际上比list=new List<int>(10000000);list.AddRange(range)要低效得多,甚至比list=new List<int>(range.Count());list.AddRange(range)还要低效(因为后者将确保列表不会超过必要的大小)。 - Tim Schmelter
我不明白的是为什么需要一个列表?SelectList构造函数需要IEnumerable。这只是为了保证查询只执行一次吗? - phoog
1个回答

21

e.ToList<T>()在底层实现上的代码是:

return new List<T>(e);

List<T>(IEnumerable<T> e)构造函数实际上只是在内部调用this.AddRange(e)

换句话说,这两个代码片段将以完全相同的方式执行完全相同的操作。


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