gpt4 book ai didi

c# - IList 和 IReadOnlyList

转载 作者:IT王子 更新时间:2023-10-29 04:05:10 26 4
gpt4 key购买 nike

如果我有一个方法需要一个参数,

  • 有一个 Count属性(property)
  • 有一个整数索引器(只获取)

这个参数的类型应该是什么?我会选择 IList<T>在 .NET 4.5 之前,因为没有其他可索引的集合接口(interface)和数组实现它,这是一个很大的优势。

但是 .NET 4.5 引入了新的 IReadOnlyList<T>接口(interface),我希望我的方法也支持它。我如何编写此方法以同时支持 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> 也是如此类(class)。这使得很难找到实现 IList<T> 的类。但不是 IReadOnlyList<T> .

最佳答案

你在这里运气不好。 IList<T>没有实现 IReadOnlyList<T> . List<T>确实实现了这两个接口(interface),但我认为这不是您想要的。

但是,您可以使用 LINQ:

  • Count()扩展方法在内部检查实例实际上是否是一个集合,然后使用 Count属性(property)。
  • ElementAt()扩展方法在内部检查实例是否实际上是一个列表,然后使用索引器。

关于c# - IList<T> 和 IReadOnlyList<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12838122/

26 4 0