【发布时间】:2012-10-02 00:47:10
【问题描述】:
如果我有一个方法需要一个参数,
- 有一个
Count属性 - 具有整数索引器(仅限获取)
这个参数的类型应该是什么?我会在 .NET 4.5 之前选择 IList<T>,因为没有其他可索引的集合接口用于此,并且数组实现了它,这是一个很大的优势。
但是.NET 4.5 引入了新的IReadOnlyList<T> 接口,我希望我的方法也支持它。我怎样才能编写这个方法来支持IList<T>和IReadOnlyList<T>而不违反像DRY这样的基本原则?
编辑:丹尼尔的回答给了我一些想法:
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> 的类。
【问题讨论】:
-
2021 年 1 月更新:看起来它会及时为 .NET 5 完成,但它仍然是一个悬而未决的问题:github.com/dotnet/runtime/issues/31001
标签: c# .net collections interface .net-4.5