简体   繁体   English

覆盖IEnumerable <T> 哪里

[英]Override IEnumerable<T> Where

I've written a class that implements IEnumerable : 我写了一个实现IEnumerable的类:

public class MyEnumerable : IEnumerable<MyClass>
{ 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
    public IEnumerator<MyClass> GetEnumerator()
    {
        //Enumerate
    }
}

I'd like to "override" the Where method. 我想“覆盖” Where方法。 What I want to do is : 我想做的是:

MyEnumerable myEnumerable = new MyEnumerable();
MyEnumerable myEnumerable2 = myEnumerable.Where(/*some predicate*/);

This is not possible for the moment because myEnumerable.Where() returns an IEnumerable. 目前这是不可能的,因为myEnumerable.Where()返回IEnumerable。 What I want is that myEnumerable.Where() returns a MyEnumerable. 我想要的是myEnumerable.Where()返回一个MyEnumerable。

Is that possible to do this ? 可以这样做吗?

Thank you 谢谢

Sure - just add a Where method to MyEnumerable . 当然,只需向MyEnumerable添加Where方法。 The Linq Where method is an extension method, so it's not technically an override. Linq Where方法是扩展方法,因此从技术上讲,它不是替代方法。 you're "hiding" the linq method. 您正在“隐藏” linq方法。

public class MyEnumerable : IEnumerable<MyClass>
{ 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
    public IEnumerator<MyClass> GetEnumerator()
    {
        //Enumerate
    }

    public MyEnumerable Where()
    {
       // implement `Where`
    }
}

There are some caveats, though: 但是,有一些警告:

  • Your Where method will only be called if the declared type is MyEnumerable - it will not be called on variables of type IEnumerable<MyClass> (or any collection that implements it, like List<MyClass> 仅在声明的类型为MyEnumerable下才会调用Where方法-不会在IEnumerable<MyClass>类型的变量(或实现它的任何集合,如List<MyClass>上调用
  • There are several overloads of Where that will need to be implemented as well if you want to maintain consistently with Linq. 如果要与Linq保持一致,则还需要实现Where几个重载。

Update 更新资料

From your comment your enumerator is a lazy file enumerator and you want to be able to select items from it based on a predicate and still have the laziness. 根据您的评论,您的枚举器是一个惰性文件枚举器,您希望能够基于谓词从中选择项,并且仍然很懒。

You could create another class inheriting that class or an interface to help with this. 您可以创建另一个继承该类的类或一个接口来帮助实现此目的。

Here is an example 这是一个例子

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));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM