views:

332

answers:

3

I have an ObservableCollection, and I'd like to set the content of an IList to this one. Now I could just create a new instance of the collection..:

public ObservableCollection<Bar> obs = new ObservableCollection<Bar>(); 
public void Foo(IList<Bar> list)
{
    obs = new ObservableCollection<Bar>(list); 
}

But how can I actually take the content of the IList and add it to my existing ObservableCollection? Do I have to loop over all elements, or is there a better way?

public void Foo(IList<Bar> list)
{
   foreach (var elm in list)
       obs.Add(elm); 
}
A: 

Looping is the only way, since there is no AddRange equivalent for ObservableCollection.

Richard Szalay
+3  A: 

You could write your own extension method if you are using C#3+ to help you with that (I haven't tested the code below, so there might be some errors, but you should get the idea):

public void AddRange<T>(this ObservableCollection<T> coll, IEnumerable<T> items)
{
    foreach (var item in items)
    {
        coll.Add(item);
    }
}
RaYell
+1 for extension method idea
Richard Szalay
Microsoft's [Prism](http://compositewpf.codeplex.com/) project for WPF includes a similar extension method (although, their version returns the collection, rather than `void`, to support method chaining).Just reference Microsoft.Practices.Composite.dll and add `using Microsoft.Practices.Composite;`.
totorocat
+2  A: 

You could do

public void Foo(IList<Bar> list)
{
    list.ToList().ForEach(obs.Add);
}

or as an extension method,

    public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items)
    {
        items.ToList().ForEach(collection.Add);
    }    
AdamRalph
Thx! Went with the ToList.ForEach approach for now. Will consider extension method if I need this more than one place..
stiank81
The `Enumerable.ToList` extension method needlessly allocates a new `List<T>`. I'd probably recommend RaYell's answer.
Richard Szalay
@Richard - that is true although under the hood this does new List<T>(list) - which internally calls ((ICollection<T>)list).CopyTo(T[]) which in most implementations of IList<T> (e.g. List<T>) calls a native (external) array copy function. this should be quite efficient and only involve (at most) an atomic copy of the necessary references rather than iteration of members.
AdamRalph