I have a method which I'd like to take all list-like objects in my solution. Before .NET 4.5, this was simple:
public static T Method<T>(IList<T> list)
{
// elided
}
However, .NET 4.5 introduced IReadOnlyList<T>
, which this method should also apply to.
I can't just change the signature to take an IReadOnlyList<T>
, as there are places where I apply the method to something specifically typed as an IList<T>
.
The algorithm can't run on IEnumerable<T>
, and it's used too frequently (and with too large objects) to take an IEnumerable<T>
and create a new List<T>
on every call.
I've tried adding an overload:
public static T Method<T>(IReadOnlyList<T> list)
{
// elided
}
... but this won't compile for anything which implements both interfaces (T[]
, List<T>
, and numerous other types), as the compiler can't determine which method to use (particularly annoying as they have the same body, so it doesn't matter).
I don't want to have to add overloads of Method
which take T[]
, and List<T>
, and every other type which implements both interfaces.
How should I accomplish this?
This might be one of those occasions where actually checking the runtime type is useful:
public static T Method<T>(IEnumerable<T> source)
{
if (source is IList<T> list)
return Method(list);
if (source is IReadOnlyList<T> readOnly)
return Method(readOnly);
return Method(source.ToList() as IList<T>);
}
private static T Method<T>(IReadOnlyList<T> list) { ... }
private static T Method<T>(IList<T> list) { ... }
You still have to duplicate code in the sense that you need seperate implementations for IList
and IReadOnlyList
because there is no common interface you can leverage, but you at least avoid the ambigous call issue.
Your likely best bet is to do a global search and replace of IList
to IReadOnlyList
. If there are no compiler errors then you should be fine.
You should only receive compiler errors if you are using IList.Add
- which is foolhardy anyway, since arrays don't support Add
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With