4

so I was wondering if someone would make a very thorough explanation of what exactly I have done here, I know what im working with, and what the meaning of the code is, however, if I were to explain it, I would be clueless.

public static IEnumerable<TSource> VisitorWhere<TSource>(this IEnumerable<TSource> enumerable, Predicate<TSource> CompareMethod)
{
    ICollection<TSource> temp = new List<TSource>();

    foreach (TSource item in enumerable)
    {
        if(CompareMethod(item))
        {
            temp.Add(item);
        }
    }
    return temp;
}
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • Here: https://msdn.microsoft.com/en-us//library/bb383977.aspx – rory.ap Oct 04 '16 at 11:52
  • I know, Ive looked that that already, but it doesnt really help me understand it. –  Oct 04 '16 at 11:53
  • 4
    This is just an eager version of `Enumerable.Where`. – Lee Oct 04 '16 at 12:02
  • You have generated a help function to use with Linq. Custom Classes don't implement all the library library features that Linq needed to enumerate, and compare. So you created a method that defines enumerable for you custom class. – jdweng Oct 04 '16 at 12:29

2 Answers2

10

Your code above is simply an extension method that iterates a collection and returns only the items that match a predicate:

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.

I'd not call this a LINQ method. Most LINQ methods are fluent (you can chain them), as you did with your extension method, but what you are missing in your case is that the execution of similar methods like Where is deferred (i.e. items are consumed one after the other and only when they are requested). Yours on the other hand executes immediately and consumes the whole input sequence all at once.

Look into yield return:

public static IEnumerable<TSource> VisitorWhere<TSource>(this IEnumerable<TSource> enumerable, Predicate<TSource> compareMethod)
{
   foreach (TSource item in enumerable)
   {
      if (compareMethod(item))
      {
         yield return item;
      }
   }
}
Sebastian Brosch
  • 42,106
  • 15
  • 72
  • 87
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • 1
    You're welcome. Note btw.: It's spelled "deferred" (not "differed") ;-) Oh, another note (though I didn't edit this in): You're basically stating that deferred execution is a required characteristic for LINQ methods. That is not quite true. There are several LINQ operators that evaluate a sequence eagerly; e.g. `Count`, `OrderBy`, etc. They have to, in order to do what they're supposed to do. On the other hand, `Where` can still do what it's supposed to while evaluating lazily / executing in a deferred manner, so I agree with you that this is how it should be implemented. – stakx - no longer contributing Oct 04 '16 at 14:01
  • @stakx - Ya, what I meant that most are fluent and deferred. Basically for it to be a LINQ method it has to be under that namespace :) but for the purpose of his need it is the deferred part of it. – Gilad Green Oct 04 '16 at 15:13
1

It's a way to e.g. filter a list of visitors using a condition you provide in the predicate. If you have a list:

List<string> visitorList = new List<string>(){"dave", "clare", "steve"};

With the following predicate:

Predicate<string> daveFinder = (string s) => {return s=="dave";};

Using your extension method will return an IEnumerable with one item - "dave":

List<string> daveVisitors = visitorList.VisitorWhere(daveFinder).ToList();

The joy of generic types means that you are free to provide an IEnumerable containing any flavor of objects and a corresponding Predicate and your extension method will still work.

Will Jenkins
  • 9,507
  • 1
  • 27
  • 46