IT Story/C# & WPF

How to select certain Elements

Hoyami7 2019. 12. 5. 10:43
반응형

What most of those Linq extension methods do is basically creating wrapper objects which also implement IEnumerable / IEnumerator around the input IEnumerable / IEnumerator. So when you call MoveNext on the wrapper it will in turn call MoveNext on the input enumerator to get one element from the input and returns that one as Current.

For example:

 List<string> someList;
 IEnumerable<string> myEnumerable = someList.Where(x=>x != "not me");
 foreach(string s in myEnumerable)
 {
     Debug.Log(s);
 }

Note that in the second line we just create the "wrapper" IEnumerable. We don't iterate it. The foreach loop will actually call GetEnumerator and then iterate over each item that the wrapper object returns, While iterating the wrapper will in turn iterate over the input enumerator. This "chaining" can go crazy.

Predicate function

A predicate is actually a method that will tell the caller if a certain object satisfies a certain criteria. It's actually just a method that takes an object as parameter and returns a boolean. In most cases when using Linq you would use Lambda expression / anonymous method, but you can use actual methods as well. The example above could be written as:

 static bool FilterOutNotMe(string aObj)
 {
     if (aObj == "not me")
         return false;
     return true;
 }
 
 IEnumerable<string> myEnumerable = someList.Where(FilterOutNotMe);

A Lambda expression is basically just an anonymous method. The syntax is fairly easy. You first have to specify the paramters of your method, followed by the lambda operator =>. Behind that operator you actually specify the body of your method. The formal syntax would look like this:

 

 // written by me from scratch
 class Where_Enumerator<T> : IEnumerator<T>
 {
     IEnumerator<T> input;
     Predicate<T> condition;
     public T Current { get { return input.Current; } }
     public bool MoveNext()
     {
         while(true)
         {
             if (!input.MoveNext())
                 return false;
             if (condition(input.Current))
                 return true;
         }
     }
 }
반응형