views:

221

answers:

6

I have a class property exposing an internal IList<> through

System.Collections.ObjectModel.ReadOnlyCollection<>

How can I pass a part of this ReadOnlyCollection<> without copying elements into a new array (I need a live view, and the target device is short on memory)? I'm targetting Compact Framework 2.0.

+1  A: 

You can always write a class that implements IList and forwards all calls to the original list (so it doesn't have it's own copy of the data) after translating the indexes.

Nir
+1  A: 

You could use yield return to create a filtered list

IEnumerable<object> FilteredList()
{
    foreach( object item in FullList )
    {
        if( IsItemInPartialList( item )
            yield return item;
    }
}
Mendelt
A: 

How do the filtered elements need to be accessed? If it's through an Iterator then maybe you could write a custom iterator that skips the elements you don't want publicly visible?

If you need to provide a Collection then you might need to write your own Collection class, which just proxies to the underlying Collection, but prevents access to the elements you don't want publicly visible.

(Disclaimer: I'm not very familiar with C#, so these are general answers. There may be more specific answers to C# that work better)

Herms
+7  A: 

Try a method that returns an enumeration using yield:

IEnumerable<T> FilterCollection<T>( ReadOnlyCollection<T> input ) {
    foreach ( T item in input )
        if (  /* criterion is met */ )
            yield return item;
}
Keith
+1  A: 

Depending on how you need to filter the collection, you may want to create a class that implements IList (or IEnumerable, if that works for you) but that mucks about with the indexing and access to only return the values you want. For example

class EvenList: IList
{
    private IList innerList;
    public EvenList(IList innerList)
    {
         this.innerList = innerList;
    }

    public object this[int index]
    {
        get { return innerList[2*i]; }
        set { innerList[2*i] = value; }
    }
    // and similarly for the other IList methods
}
Blair Conrad
+3  A: 

These foreach samples are fine, though you can make them much more terse if you're using .NET 3.5 and LINQ:

return FullList.Where(i => IsItemInPartialList(i)).ToList();
Brad Wilson