次のようなパラメータを必要とするメソッドがある場合、
Count
プロパティがあります- 整数インデクサーがあります(get-only)
このパラメータのタイプはどうあるべきですか?IList<T>
これには他にインデックス可能なコレクションインターフェイスがなく、配列がそれを実装しているため、.NET4.5より前を選択しました。これは大きなプラスです。
しかし、.NET 4.5は新しいIReadOnlyList<T>
インターフェースを導入しており、私のメソッドもそれをサポートしたいと思っています。DRYのような基本原則に違反することなく、両方IList<T>
をサポートするためにこのメソッドを作成するにはどうすればよいですか?IReadOnlyList<T>
編集:ダニエルの答えは私にいくつかのアイデアを与えました:
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>
。