If I have a method that requires a parameter that,
Count
propertyWhat should the type
If you're more concerned with maintaining the principal of DRY over performance, you could use dynamic, like so:
public void Do(IList collection)
{
DoInternal(collection, collection.Count, i => collection[i]);
}
public void Do(IReadOnlyList collection)
{
DoInternal(collection, collection.Count, i => collection[i]);
}
private void DoInternal(dynamic collection, int count, Func indexer)
{
// Get the count.
int count = collection.Count;
}
However, I can't say in good faith that I'd recommend this as the pitfalls are too great:
collection
in DoInternal
will be resolved at run time. You lose type safety, compile-time checks, etc.Your helper suggestion is the most useful, but I think you should flip it around; given that the IReadOnlyList
That said, you should create an AsList
wrapper, which takes an IReadOnlyList
and returns a wrapper in an IList
implementation.
However, if you want to emphasize on your API that you are taking an IReadOnlyList
(to emphasize the fact that you aren't mutating the data), then the AsReadOnlyList
extension that you have now would be more appropriate, but I'd make the following optimization to AsReadOnly
:
public static IReadOnlyList AsReadOnly(this IList collection)
{
if (collection == null)
throw new ArgumentNullException("collection");
// Type-sniff, no need to create a wrapper when collection
// is an IReadOnlyList *already*.
IReadOnlyList list = collection as IReadOnlyList;
// If not null, return that.
if (list != null) return list;
// Wrap.
return new ReadOnlyWrapper(collection);
}