162

How to convert IEnumerable to ObservableCollection?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
KentZhou
  • 24,805
  • 41
  • 134
  • 200

5 Answers5

252

As per the MSDN

var myObservableCollection = new ObservableCollection<YourType>(myIEnumerable);

This will make a shallow copy of the current IEnumerable and turn it in to a ObservableCollection.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Is this quicker than using a ForEach loop to insert the items one by one into the collection? – Rexxo Aug 31 '16 at 12:49
  • 7
    @Rexxo it will be slightly faster to do it with the constructor. Internally [it is using a `foreach`](http://referencesource.microsoft.com/System/compmod/system/collections/objectmodel/observablecollection.cs.html#cfaa9abd8b214ecb) to copy the items to the internal collection, however if you do the foreach and call `Add` [it will be going through `InsertItem`](http://referencesource.microsoft.com/System/compmod/system/collections/objectmodel/observablecollection.cs.html#767bf62bf4a3a7c1) which does a lot of extra stuff that is unessesary when initially filling causing it to be slightly slower. – Scott Chamberlain Aug 31 '16 at 13:05
  • Simples and the best answer – 27k1 Sep 30 '18 at 12:51
82
  1. If you're working with non-generic IEnumerable you can do it this way:

    public ObservableCollection<object> Convert(IEnumerable original)
    {
        return new ObservableCollection<object>(original.Cast<object>());
    }
    
  2. If you're working with generic IEnumerable<T> you can do it this way:

    public ObservableCollection<T> Convert<T>(IEnumerable<T> original)
    {
        return new ObservableCollection<T>(original);
    }
    
  3. If you're working with non-generic IEnumerable but know the type of elements, you can do it this way:

    public ObservableCollection<T> Convert<T>(IEnumerable original)
    {
        return new ObservableCollection<T>(original.Cast<T>());
    }
    
H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144
Elisha
  • 23,310
  • 6
  • 60
  • 75
39

To make things even more simple you can create an Extension method out of it.

public static class Extensions
{
    public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> col)
    {
        return new ObservableCollection<T>(col);
    }
}

Then you can call the method on every IEnumerable

var lst = new List<object>().ToObservableCollection();
Community
  • 1
  • 1
markwilde
  • 1,892
  • 1
  • 16
  • 23
2
ObservableCollection<decimal> distinctPkgIdList = new ObservableCollection<decimal>();
guPackgIds.Distinct().ToList().ForEach(i => distinctPkgIdList.Add(i));

// distinctPkgIdList - ObservableCollection
// guPackgIds.Distinct() - IEnumerable 
joergl
  • 2,850
  • 4
  • 36
  • 42
Sudharshan
  • 348
  • 1
  • 9
1

The C# Function to Convert the IEnumerable to ObservableCollection

private ObservableCollection<dynamic> IEnumeratorToObservableCollection(IEnumerable source)
    {

        ObservableCollection<dynamic> SourceCollection = new ObservableCollection<dynamic>();

        IEnumerator enumItem = source.GetEnumerator();
        var gType = source.GetType();
        string collectionFullName = gType.FullName;
        Type[] genericTypes = gType.GetGenericArguments();
        string className = genericTypes[0].Name;
        string classFullName = genericTypes[0].FullName;
        string assName = (classFullName.Split('.'))[0];

        // Get the type contained in the name string
        Type type = Type.GetType(classFullName, true);

        // create an instance of that type
        object instance = Activator.CreateInstance(type);
        List<PropertyInfo> oProperty = instance.GetType().GetProperties().ToList();
        while (enumItem.MoveNext())
        {

            Object instanceInner = Activator.CreateInstance(type);
            var x = enumItem.Current;

            foreach (var item in oProperty)
            {
                if (x.GetType().GetProperty(item.Name) != null)
                {
                    var propertyValue = x.GetType().GetProperty(item.Name).GetValue(x, null);
                    if (propertyValue != null)
                    {
                        PropertyInfo prop = type.GetProperty(item.Name);
                        prop.SetValue(instanceInner, propertyValue, null);
                    }
                }
            }

            SourceCollection.Add(instanceInner);
        }

        return SourceCollection;
    }
B.Balamanigandan
  • 4,713
  • 11
  • 68
  • 130
  • 1
    Very useful!!! Thanks. But it needs two improvements: 1) call it with `this IEnumerable source, string assemblyFullyQualifiedName` and do a `Type type = Type.GetType( classFullName + $", {assemblyFullyQualifiedName}")`; 2) only SetValue if you can; so instead of `if (propertyValue != null)` do a `if (propertyValue != null && item.CanWrite)` – Marcelo Scofano Diniz Aug 02 '21 at 03:52