如果我有一个方法需要一个参数,
Count
属性此参数的类型应该是什么?我会在.NET 4.5之前选择
IList<T>
,因为没有其他可索引的集合接口(interface),并且数组可以实现它,这是一个很大的优点。但是.NET 4.5引入了新的
IReadOnlyList<T>
接口(interface),我也希望我的方法也支持该接口(interface)。如何编写此方法以同时支持IList<T>
和IReadOnlyList<T>
而又不违反DRY等基本原理?编辑:Daniel的回答给了我一些想法:
public void Foo<T>(IList<T> list)
=> Foo(list, list.Count, (c, i) => c[i]);
public void Foo<T>(IReadOnlyList<T> list)
=> Foo(list, list.Count, (c, i) => c[i]);
private void Foo<TList, TItem>(
TList list, int count, Func<TList, int, TItem> indexer)
where TList : IEnumerable<TItem>
{
// Stuff
}
编辑2:或我也可以接受
IReadOnlyList<T>
并提供这样的帮助器:public static class CollectionEx
{
public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> list)
{
if (list == null)
throw new ArgumentNullException(nameof(list));
return list as IReadOnlyList<T> ?? new ReadOnlyWrapper<T>(list);
}
private sealed class ReadOnlyWrapper<T> : IReadOnlyList<T>
{
private readonly IList<T> _list;
public ReadOnlyWrapper(IList<T> list) => _list = list;
public int Count => _list.Count;
public T this[int index] => _list[index];
public IEnumerator<T> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
然后我可以像
Foo(list.AsReadOnly())
这样称呼它编辑3:数组同时实现
IList<T>
和IReadOnlyList<T>
,List<T>
类也实现。这使得很难找到实现IList<T>
而不是IReadOnlyList<T>
的类。 最佳答案
您真不走运。 IList<T>
没有实现IReadOnlyList<T>
。 List<T>
确实实现了两个接口(interface),但我认为这不是您想要的。
但是,您可以使用LINQ:
Count()
扩展方法在内部检查该实例是否实际上是一个集合,然后使用Count
属性。 ElementAt()
扩展方法在内部检查该实例是否实际上是列表,然后使用索引器。 关于c# - IList <T>和IReadOnlyList <T>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12838122/