2015-02-11 46 views
0

我試圖用MvvmLight做視圖模型在Xamarin的Android結合製作ICollection的工作作爲IList的

MvvmLight接受的IList作爲數據綁定的參數,但所有的ViewModels使用的ICollection(該應用程序最初僅適用於Windows目前正在遷移到Android,我們不能將ICollection更改爲IList)

我知道IList擴展了ICollection作爲IList?

鑄造是顯而易見的解決方案,但不是所有的ICollection實現IList,所以我們正在努力避免

我們也不能使原有集合的副本,因爲我們需要雙向綁定

+2

您可以創建一個實現IList的包裝器,以將調用路由到基礎集合。這也可以部分地模仿索引(假設Xamarin使用這個)和ElementAt。但是,如果消費實現試圖插入,這會中斷,因爲您無法執行隨機訪問插入;在這種情況下,您需要重新構建整個Collection,然後再將其添加回去。 – 2015-02-11 23:58:20

回答

4

由於不保證任意ICollection<T>也是IList<T>,最簡單的方法是使用Adapter Pattern:編寫一個薄墊片,提供您需要的接口(IList<T>)。

IList<T>是一個非常簡單的界面,你應該能夠做到沿着這些線路(見下面的例子)的東西,儘管人們可能會注意到,IList<T>提供了某些功能,是根本不具有任意ICollection<T>實現兼容。根據消費者使用哪些特定功能,您可能會丟棄NotSupportedException

人們可能會注意到,你可以在你的適配器得到一個有點小聰明,用反射詢問後備存儲—我下面的例子做一個簡單的版本,它的實際能力,努力鑄造後備存儲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() ; 
    } 

}