Converting from IEnumerable to List
You can do this very simply using LINQ.
Make sure this using is at the top of your C# file:
using System.Linq;
Then use the ToList
extension method.
Example:
IEnumerable<int> enumerable = Enumerable.Range(1, 300);
List<int> asList = enumerable.ToList();
How I can convert System.Collection.IEnumerable to ListT in c#?
You can use the following:
IEnumerable myEnumerable = GetUser();
List<User> myList = myEnumerable.Cast<User>().ToList();
As Lasse V. Karlsen suggest in his comment instead of Cast<User>
you can also use OfType<User>();
If your IEnumerable is generic by default which I don't think because of your namespace in question: System.Collection.IEnumerable you could easily use:
IEnumerable<User> myEnumerable = GetUser();
List<User> myList = myEnumerable.ToList();
Fastest way to convert IEnumerableT to ListT in C#
When it comes to List<T>
essentially you have 2 approaches, which I am trying to discuss below. For the sake of clarity lets assume, allocation of the List<T>
takes constant time (C), adding an element to the List<T>
also takes constant time.
Create empty List<T>
and populate it
List<int> list = new List<int>(); // C
foreach(int i in iterator)
{
list.Add(i); //n*C
}
as you can see this approach takes n*C + C time, so if you neglect the C the complexity is O(n).
Create List<T>
based on the other IEnumerable<T>
List<int> list = new List<int>(iterator);
however, there is a small difference regards the type of iterator:
if the iterator is
ICollection<T>
var array = new T[ICollection.Count] // C
ICollection.CopyTo(array) // by MSDN O(n)if the iterator is
IEnumerable<T>
, the same as creating empty and add item by item
So, if you analyze the complexity you cannot avoid O(n) complexity.
BUT...
There is one caveat with the List<T>
growth and capacity which might impact performances. The default List<T>
capacity is 4 and if you add more than 4 elements to the List<T>
the new underlying array, twice of the current size, will be allocated and the elements will be copied...this process will repeat again when we reach the capacity of the List<T>
. You can imagine how much unnecessary copying you might have. In order to prevent this, the best option is to initialize List<T>
with capacity in advance or use the List<T>(ICollection<T>)
ctor.
// benchmark example
var enumerable = Enumerable.Repeat(1, 1000000);
var collection = enumerable.ToList();
Stopwatch st = Stopwatch.StartNew();
List<int> copy1 = new List<int>(enumerable);
Console.WriteLine(st.ElapsedMilliseconds);
st = Stopwatch.StartNew();
List<int> copy2 = new List<int>(collection);
Console.WriteLine(st.ElapsedMilliseconds);
How to convert IEnumerableIEnumerableT to Liststring?
For any IEnumerable<IEnumerable<T>>
we can simply call SelectMany
.
Example:
IEnumerable<IEnumerable<String>> lotsOStrings = new List<List<String>>();
IEnumerable<String> flattened = lotsOStrings.SelectMany(s => s);
Casting IEnumerableT to ListT
As already suggested, use yourEnumerable.ToList()
. It enumerates through your IEnumerable
, storing the contents in a new List
. You aren't necessarily copying an existing list, as your IEnumerable
may be generating the elements lazily.
This is exactly what the other answers are suggesting, but clearer. Here's the disassembly so you can be sure:
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return new List<TSource>(source);
}
Convert IEnumerable to List of properties
Just use the Linq Select
method:
var events = ...
var eventIDs = events.Select(e => e.Id);
This will return an IEnumerable<int>
, which should be enough for most purposes. However, if you really want a List<int>
you can just call the ToList
method:
var eventIDs = events.Select(e => e.Id).ToList();
Converting IEnumerable to a List, will the List follow the same order?
Well, it depends. IEnumerable
can be basically anything, so a List<T>
where the order is guaranteed or a database query where it depends on if there is a OrderBy
or not.
If you are talking about in memory collections then the order is guaranteed if the collection itself guarantees it(Dictionar<TKey, TValue>
for example does not).
If you ask if Enumerable.ElementAt(i)
returns always the same as list[i]
if list
is a List<T>
, then yes, it guarantees it because the implementation checks first if the sequence implements IList<T>
(like arrays or lists) and then uses the index:
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) {
if (source == null) throw Error.ArgumentNull("source");
IList<TSource> list = source as IList<TSource>;
if (list != null) return list[index];
if (index < 0) throw Error.ArgumentOutOfRange("index");
using (IEnumerator<TSource> e = source.GetEnumerator()) {
while (true) {
if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
if (index == 0) return e.Current;
index--;
}
}
}
This is documented so you can rely on this behavior.
If the type of source implements
IList<T>
, that implementation is used
to obtain the element at the specified index. Otherwise, this method
obtains the specified element.
Related Topics
Capturing Binary Output from Process.Standardoutput
How to Initialize a C# Dictionary with Values
Performance of Static Methods VS Instance Methods
Databind the Source Property of the Webbrowser in Wpf
How to Read All Files Inside Particular Folder
Algorithm to Find Which Numbers from a List of Size N Sum to Another Number
Open Default Mail Client Along with a Attachment
JSON.Net Serialize Specific Private Field
How to Pass Data from Mainwindow to a User Control That's Inside the Mainwindow
Singleton by Jon Skeet Clarification
How to Save Console.Writeline Output to Text File
How to Stop Flickering C# Winforms