我正在尝试使用MvvmLight在Xamarin Android中执行ViewModel绑定
MvvmLight接受IList作为数据绑定的参数,但所有的视图模型都使用ICollection(该应用程序最初只是Windows,目前正在迁移到Android,我们无法将ICollection更改为IList)
我知道IList扩展了ICollection,所以..我想这更像是一种模式,我们将这些ICollection作为IList工作的最佳方式是什么?
Casting是一个显而易见的解决方案,但并非所有ICollection都实现了IList,所以我们试图避免这种情况
我们也无法复制原始集合,因为我们需要双向绑定
答案 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() ;
}
}