I have implemented the following class:
class LazyList<T> : IList<T>
{
public LazyList(IEnumerable<T> enumerable) { }
}
I need to use this class with non-generic legacy System.Collections
. I have solved half of the problem by using IEnumerable.Cast<object>()
as described here https://stackoverflow.com/a/776407/2109230/.
However, I need to cast LazyList<T>
to non-generic IList
to complete the refactor process. How can I achieve this?
LazyList basically helps me refactor a method that returns IList after iterating an IDataReader. I use data returned from this method to send some updates over WebSocket. The point is to send data constantly, not after processing the entire IDataReader. I have used yield return to return a lazy IEnumerable, but other methods require the refactored method to return IList. So, I came up with the idea of LazyList.
There are actually two methods, one returning IList<T>
, which I have refactored successfully, and another returning IList
. I wanted to see if there is a simpler way to refactor the version returning IList, without implementing non-generic LazyList. However, I did that and it wasn't that bad.
You should follow the pattern the List<T>
does - implement both interfaces and use explicit interface implementations to remove some duplication (see the source code) and limit the exposed contract. Something to get you started:
class LazyList<T> : IList<T>, IList
{
public LazyList(IEnumerable<T> enumerable) { }
public void Add(T item) => throw new NotImplementedException();
public int Count { get; }
public int Add(object? item)
{
Add((T)item!); // call to the generic implementation
return Count - 1;
}
int IList.IndexOf(object? item)
{
if (IsCompatibleObject(item))
{
return IndexOf((T)item!); // call to generic
}
return -1;
}
public int IndexOf(T item) => throw new NotImplementedException();
private static bool IsCompatibleObject(object? value) => (value is T) || (value == null && default(T) == null);
// ...
}