At the moment I use List<int> ints = tuple.Item2.Select(s => s.Value).ToList() but this looks inefficient when tuple.Item2 has 1000's of items. Any better way to achieve this? except using a for loop.
2 Answers
The built-in way to convert each element in one List<T1> and store the result in another List<T2> is List<T1>.ConvertAll.
List<int> ints = tuple.Item2.ConvertAll(s => s.Value);
Unlike .Select(...).ToList() or .Cast(...).ToList(), this method knows the list size in advance, and prevents unnecessary reallocations that .ToList() cannot avoid.
For this to work, tuple.Item2 must really be a List<int?>. It's not an extension method, it cannot work on the generic IEnumerable<int?> interface.
2 Comments
s => s.GetValueOrDefault() is faster than just s => s.Value. This may seem surprising, but the reason is that .GetValueOrDefault() always and unconditionally exposes the backing field (value), while the .Value property first checks the Boolean field (hasValue) to see if it is true or false, and only then exposes that backing field (or throws if hasValue was false). The Nullable<> struct ensures that the backing field always has its default value in the case where we are modeling a "null", so that is why the behavior of .GetValueOrDefault() is safe.s => s ?? 0.you can simply use Linq Cast<> to achieve this .
List<int> ints = tuple.Item2.Cast<int>();
but if an element cannot be cast to type TResult, this method will throw an exception.you have to consider catching exception.
7 Comments
.Where(x => x.HasValue) to check nullsToList() on the end.
s.HasValue == false...