获取原始列表并将其转换为可为空的基元列表的最快方法是什么 例如:c#
中的List<int>
到List<int?>
简单的解决方案,创建新列表并使用foreach循环添加每个项目需要花费太多时间。
答案 0 :(得分:40)
没有办法比创建新列表更快:
var newList = list.Select( i => (int?)i ).ToList();
然而,使用LINQ比使用裸循环慢。
最快的方法是使用具有预先分配容量的List<int?>
:
List<int?> newList = new List<int?>(list.Count); // Allocate enough memory for all items
foreach (var i in list)
newList.Add(i);
如果您正在寻找列表项的就地类型转换,则无法实现。
答案 1 :(得分:11)
而不是Select
你可以坚持使用Cast
LINQ-operator:
List<int> first = new List<int>() {1, 2, 3};
List<int?> second = first.Cast<int?>().ToList();
答案 2 :(得分:6)
如果你想知道什么是更快的解决方案,你应该通过三种不同的方式做一点benchmark:
List<int> list = Enumerable.Range( 0, 10000 ).ToList( );
Stopwatch sw = Stopwatch.StartNew( );
for ( int i = 0; i < 100000; i++ ) {
List<int?> newList = new List<int?>( );
foreach( int integer in list )
newList.Add( ( int? ) integer );
}
sw.Stop( );
TimeSpan timespan = sw.Elapsed;
Console.WriteLine( String.Format( "Foreach: {0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10 ) );
sw.Restart( );
for ( int i = 0; i < 100000; i++ ){
List<int?> newList = list.Select( x => ( int? ) x ).ToList( );
}
sw.Stop( );
timespan = sw.Elapsed;
Console.WriteLine( String.Format( "LINQ-Select: {0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10 ) );
sw.Restart( );
for ( int i = 0; i < 100000; i++ ){
List<int?> newList = list.Cast<int?>( ).ToList( );
}
sw.Stop();
timespan = sw.Elapsed;
Console.WriteLine( String.Format( "LINQ-Cast: {0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10 ) );
结果:
我们可以期待最好的方法是第一个解决方案(foreach
),这意味着循环遍历元素,强制转换并将它们添加到新列表中。
答案 3 :(得分:0)
这不是一个新问题,但我目前使用此代码;我希望它可以帮助其他人提出同样的问题: 预先分配+ Linq 的列表:
var branchIds = new List<int?>(branches.Count);
branchIds.AddRange(branches.Select(int.Parse).Select(brId => (int?)brId));