Заставь ICollection работать как IList
Я пытаюсь использовать MvvmLight для привязки ViewModel в Xamarin Android
MvvmLight принимает IList в качестве параметра для привязки данных, но все модели представления используют ICollection (изначально приложение было только для Windows и в настоящее время мигрирует на Android, мы не можем изменить ICollection на IList)
Я знаю, что IList расширяет ICollection, так что... Я думаю, это скорее шаблонная вещь, как лучше всего сделать так, чтобы эти ICollection работали как IList?
Кастинг является очевидным решением, но не все ICollection реализуют IList, поэтому мы пытаемся избежать этого
Мы также не можем сделать копию оригинальной коллекции, потому что нам нужно двустороннее связывание
1 ответ
Поскольку нет гарантии, что произвольный ICollection<T>
также IList<T>
самый простой способ - использовать шаблон адаптера: напишите тонкую прокладку, обеспечивающую необходимый интерфейс (IList<T>
).
IList<T>
это довольно простой интерфейс, и вы должны иметь возможность что-то делать в этом направлении (см. пример ниже), хотя можно заметить, что IList<T>
обеспечивает определенные функции, которые просто не совместимы с произвольными ICollection<T>
Реализации. В зависимости от того, что конкретно IList<T>
функции, которые потребитель / потребители используют, вы можете бросить NotSupportedException
s.
Можно также заметить, что вы могли бы стать немного умнее в своем адаптере и использовать отражение, чтобы опросить резервное хранилище на предмет его реальных возможностей - мой пример ниже представляет простую версию, пытаясь привести резервное хранилище к 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() ;
}
}