问题描述
如果我有一个需要参数的方法,
If I have a method that requires a parameter that,
- 有一个
计数
property - 有一个整数索引器(get-only)
- Has a
Count
property - Has an integer indexer (get-only)
该类型应该是什么这个参数是?我会在.NET 4.5之前选择 IList< T>
,因为没有其他可索引的集合接口,并且数组实现它,这是一个很大的优点。
What should the type of this parameter be? I would choose IList<T>
before .NET 4.5 since there was no other indexable collection interface for this and arrays implement it, which is a big plus.
但.NET 4.5引入了新的 IReadOnlyList< T>
界面,我也希望我的方法也能支持它。如何在不违反基本原则的情况下编写此方法以支持 IList< T>
和 IReadOnlyList< T>
干?
But .NET 4.5 introduces the new IReadOnlyList<T>
interface and I want my method to support that, too. How can I write this method to support both IList<T>
and IReadOnlyList<T>
without violating the basic principles like DRY?
编辑:Daniel的回答给了我一些想法:
Edit: Daniel's answer gave me some ideas:
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>
并提供如下帮助:
Edit 2: Or I could just accept an IReadOnlyList<T>
and provide a helper like this:
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>
,也是如此列表< T>
类。这使得很难找到一个实现 IList< T>
而不是 IReadOnlyList< T>
的类。
Edit 3: Arrays implement both IList<T>
and IReadOnlyList<T>
, so does the List<T>
class. This makes it pretty rare to find a class that implements IList<T>
but not IReadOnlyList<T>
.
推荐答案
你在这里运气不好。 IList< T>
未实现 IReadOnlyList< T>
。 列表< T>
确实实现了两个接口,但我认为这不是你想要的。
You are out of luck here. IList<T>
doesn't implement IReadOnlyList<T>
. List<T>
does implement both interfaces, but I think that's not what you want.
但是,你可以使用LINQ:
However, you can use LINQ:
-
Count()
扩展方法在内部检查实例是否在事实是一个集合,然后使用计数
属性。 -
ElementAt()
扩展方法在内部检查实例是否实际上是一个列表而不是使用索引器。
- The
Count()
extension method internally checks whether the instance in fact is a collection and then uses theCount
property. - The
ElementAt()
extension method internally checks whether the instance in fact is a list and than uses the indexer.
这篇关于的IList< T>和IReadOnlyList< T>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!