覆盖IEnumerable< T>在哪里
本文关键字:在哪里 IEnumerable 覆盖 | 更新日期: 2023-09-27 18:09:50
我写了一个实现IEnumerable的类:
public class MyEnumerable : IEnumerable<MyClass>
{
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<MyClass> GetEnumerator()
{
//Enumerate
}
}
我想"重写"Where方法。我想做的是:
MyEnumerable myEnumerable = new MyEnumerable();
MyEnumerable myEnumerable2 = myEnumerable.Where(/*some predicate*/);
目前这是不可能的,因为myEnumerable.Where()返回一个IEnumerable。我想要的是MyEnumerable. where()返回一个MyEnumerable。
这是可能的吗?
谢谢
当然-只需在MyEnumerable
中添加Where
方法即可。Linq Where
方法是一个扩展方法,所以它在技术上不是覆盖。你正在"隐藏"linq方法。
public class MyEnumerable : IEnumerable<MyClass>
{
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<MyClass> GetEnumerator()
{
//Enumerate
}
public MyEnumerable Where()
{
// implement `Where`
}
}
但是有一些注意事项:
- Where方法将只在声明类型为
MyEnumerable
时被调用-它不会在IEnumerable<MyClass>
类型的变量(或任何实现它的集合,如List<MyClass>
)上被调用 - 如果你想与Linq保持一致,
Where
的几个过载也需要实现。
更新
从你的注释中,你的枚举器是一个惰性文件枚举器,你希望能够根据谓词从它中选择项目,并且仍然具有惰性。
你可以创建另一个继承这个类的类或者一个接口来帮助实现这个。
下面是一个例子
public class FileItem
{
//Some properties
}
public interface IFileEnumerator : IEnumerable<FileItem>
{
IFileEnumerator Where(Func<FileItem, bool> predicate);
}
public class FileEnumerator : IFileEnumerator
{
private readonly string fileName;
public FileEnumerator(string fileName)
{
this.fileName = fileName;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<FileItem> GetEnumerator()
{
var items = new List<FileItem>();
//Read from file and add lines to items
return items.GetEnumerator();
}
public IFileEnumerator Where(Func<FileItem, bool> predicate)
{
return new MemoryEnumerator(ToEnumerable(GetEnumerator()).Where(predicate));
}
private static IEnumerable<T> ToEnumerable<T>(IEnumerator<T> enumerator)
{
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
}
public class MemoryEnumerator : IFileEnumerator
{
private readonly IEnumerable<FileItem> items;
public MemoryEnumerator(IEnumerable<FileItem> items)
{
this.items = items;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<FileItem> GetEnumerator()
{
return items.GetEnumerator();
}
public IFileEnumerator Where(Func<FileItem, bool> predicate)
{
return new MemoryEnumerator(items.Where(predicate));
}
}