這裏有一類我寫來解決這樣的情景:
public class CovariantIListAdapter<TBase, TDerived> : IList<TBase>
where TDerived : TBase
{
private IList<TDerived> source;
public CovariantIListAdapter(IList<TDerived> source)
{
this.source = source;
}
public IEnumerator<TBase> GetEnumerator()
{
foreach (var item in source)
yield return item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(TBase item)
{
source.Add((TDerived) item);
}
public void Clear()
{
source.Clear();
}
public bool Contains(TBase item)
{
return source.Contains((TDerived) item);
}
public void CopyTo(TBase[] array, int arrayIndex)
{
foreach (var item in source)
array[arrayIndex++] = item;
}
public bool Remove(TBase item)
{
return source.Remove((TDerived) item);
}
public int Count
{
get { return source.Count; }
}
public bool IsReadOnly
{
get { return source.IsReadOnly; }
}
public int IndexOf(TBase item)
{
return source.IndexOf((TDerived) item);
}
public void Insert(int index, TBase item)
{
source.Insert(index, (TDerived) item);
}
public void RemoveAt(int index)
{
source.RemoveAt(index);
}
public TBase this[int index]
{
get { return source[index]; }
set { source[index] = (TDerived) value; }
}
}
現在你可以這樣寫代碼:
List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog { Name = "Spot", MaximumBarkDecibals = 110 });
IEnumerable<Animal> animals = dogs;
IList<Animal> animalList = new CovariantIListAdapter<Animal, Dog>(dogs);
animalList.Add(new Dog { Name = "Fluffy", MaximumBarkDecibals = 120 });
的變化是兩個列表中可見,因爲沒什麼仍然只有1名單。適配器類僅傳遞通話,根據需要投射項目以實現所需的IList<TBase>
界面。
很明顯,如果你添加了除狗之外的任何東西到animalList
,它會拋出一個異常,但這符合我的需求。
+1 ......缺乏只讀在.NET(除了'IEnumerable')集合接口使得這幾乎是不可能的,但我想這是一個常見的用途 - 或許有人提出了一個可行的解決方案。 – 2011-04-29 12:44:14
您可以使用IEnumerable <>和ElementAt()一起使用,儘管語法不會很漂亮。 – 2011-04-29 12:50:36