使ICollection作为IList工作

时间:2015-02-11 23:38:29

标签: c# inheritance interface mvvm-light observablecollection

我正在尝试使用MvvmLight在Xamarin Android中执行ViewModel绑定

MvvmLight接受IList作为数据绑定的参数,但所有的视图模型都使用ICollection(该应用程序最初只是Windows,目前正在迁移到Android,我们无法将ICollection更改为IList)

我知道IList扩展了ICollection,所以..我想这更像是一种模式,我们将这些ICollection作为IList工作的最佳方式是什么?

Casting是一个显而易见的解决方案,但并非所有ICollection都实现了IList,所以我们试图避免这种情况

我们也无法复制原始集合,因为我们需要双向绑定

1 个答案:

答案 0 :(得分:4)

由于无法保证任意ICollection<T>也是IList<T>,最简单的方法是使用Adapter Pattern:编写一个提供所需接口的薄垫片( IList<T>)。

IList<T>是一个非常简单的界面,你应该可以沿着这些界面做一些事情(参见下面的例子),尽管有人可能会注意到IList<T>提供的某些功能与任意不兼容ICollection<T>实施。根据消费者使用的具体IList<T>功能,您可以抛出NotSupportedException s。

有人可能还会注意到,您可以在适配器中更聪明一些,并使用 reflection 来查询后备存储的实际功能 - 我的示例下面是一个简单版本,试图投射支持存储到IList<T>并尽可能使用该知识。

class ListAdapter<T> : IList<T>
{
    private readonly ICollection<T> backingStore;
    private readonly IList<T> list;

    public ListAdapter( ICollection<T> collection )
    {
        if ( collection == null ) throw new ArgumentNullException("collection");
        this.backingStore = collection ;
        this.list = collection as IList<T> ;

    }

    public int IndexOf( T item )
    {
        if ( list == null ) throw new NotSupportedException() ;
        return list.IndexOf(item) ;
    }

    public void Insert( int index , T item )
    {
        if ( list == null ) throw new NotSupportedException() ;
        list.Insert(index,item);
    }

    public void RemoveAt( int index )
    {
        if ( list == null ) throw new NotSupportedException() ;
        list.RemoveAt(index) ;
    }

    public T this[int index]
    {
        get
        {
            if ( list == null ) throw new NotSupportedException() ;
            return list[index] ;
        }
        set
        {
            if ( list == null ) throw new NotSupportedException() ;
            list[index] = value ;
        }
    }

    public void Add( T item )
    {
        backingStore.Add(item) ;
    }

    public void Clear()
    {
        backingStore.Clear() ;
    }

    public bool Contains( T item )
    {
        return backingStore.Contains(item) ;
    }

    public void CopyTo( T[] array , int arrayIndex )
    {
        backingStore.CopyTo( array , arrayIndex ) ;
    }

    public int Count
    {
        get { return backingStore.Count ; }
    }

    public bool IsReadOnly
    {
        get
        {
            if ( list == null ) throw new NotSupportedException() ;
            return list.IsReadOnly ;
        }
    }

    public bool Remove( T item )
    {
        return backingStore.Remove(item) ;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return backingStore.GetEnumerator() ;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return ((System.Collections.IEnumerable)backingStore).GetEnumerator() ;
    }

}