Il mio problema è che ho un metodo che può prendere una raccolta come parametro che,IList <T> e IReadOnlyList <T>
- ha una proprietà
Count
- ha un indicizzatore intero (get-only)
E non so quale tipo dovrebbe essere questo parametro. Vorrei scegliere IList<T>
prima di .NET 4.5 poiché non c'era altra interfaccia di raccolta indicizzabile per questo e gli array lo implementano, il che è un grande vantaggio.
Ma .NET 4.5 introduce la nuova interfaccia IReadOnlyList<T>
e voglio che anche il mio metodo lo supporti. Come posso scrivere questo metodo per supportare sia IList<T>
e IReadOnlyList<T>
senza violare i principi di base come DRY?
Posso convertire IList<T>
in IReadOnlyList<T>
in qualche modo in un sovraccarico?
Qual è la strada da percorrere?
Edit: la risposta di Daniel mi ha dato qualche idea, credo di poter andare con questo:
public void Foo<T>(IList<T> collection)
{
this.Foo(collection, collection.Count, i => collection[i]);
}
public void Foo<T>(IReadOnlyList<T> collection)
{
this.Foo(collection, collection.Count, i => collection[i]);
}
private void Foo<T>(
IEnumerable<T> collection,
int count,
Func<int, T> indexer)
{
// Stuff
}
Edit 2: O ho potuto solo accettare un IReadOnlyList<T>
e fornire un aiuto simile questo:
public static class CollectionEx
{
public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> collection)
{
if (collection == null)
throw new ArgumentNullException("collection");
// I now check whether it already is IReadOnlyList<T>...
// ...like casperOne has suggested.
return collection as IReadOnlyList<T>
?? new ReadOnlyWrapper<T>(collection);
}
private sealed class ReadOnlyWrapper<T> : IReadOnlyList<T>
{
private readonly IList<T> source;
public int Count { get { return this.source.Count; } }
public T this[int index] { get { return this.source[index]; } }
public ReadOnlyWrapper(IList<T> source) { this.source = source; }
public IEnumerator<T> GetEnumerator() { return this.source.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
}
Poi ho potuto chiamare Do(array.AsReadOnly())
Edit 3: Fun Fact: Array implementare sia IList<T>
eIReadOnlyList<T>
.
Domanda correlata: http://stackoverflow.com/questions/12622539/why-doesnt-generic-icollection-implement-ireadonlycollection-in-net-4-5 –