How do the parameters that LINQ methods receive work?

Asked

Viewed 335 times

6

How the parameters within these methods that receive these parameters work:

<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)

Assinatura

An example is the method Where, I know he gets one lambda expression.

Is there any way to create a method with these parameters to simulate and understand what these are: TSource, Func, bool, predicate and understand what happens when I pass, for example : p => p.Nome == "Mauricio" for the method?

What I have to study to understand this?

Intelissense

  • I’m not sure I understand what you want, the text is a bit confused. Want to see the source of Where?

  • I think if I saw Where’s source it would help me understand how it works.

  • I want to understand how this parameter works, I find it very confusing to understand what it expects, different from understanding it (int i) where the method would be: public void receivedInteiro(int i)

  • Do you want to know how it works in memory? Or in a database context, such as using Linq to Entities or Entity Framework?

  • Do you know when we open the "List.Where(" and it shows the parameter you expect to receive? So I know he gets a lambda but I know why I did it and not because I can read that parameter, I wanted to understand what he does with the lambda internally, I don’t know if it was clear :(

  • @Mauricioferraz question and comments still do not make as clear what he wants. It is not the ideal to go doing interactively, but to try to meet you, check the answers posted, indicate if this is what you want, if it is something a little different, if something is missing that is important. You should [Dit] the question and put all possible information and make the question clearer. Be careful not to invalidate existing answers.

  • @bigown thank you, that was just what I wanted, I’ve studied the extension methods and now I’m in the delegates and it works. Hug.

Show 2 more comments

2 answers

9


Has the source code of it available. In the same file has all LINQ code. All . NET code can be seen and easily on this site. No . NET Core is divided into several files.

There’s a question that talks about some details: What is System.Linq for in C#?

I think it will also be useful: Differences between declarative and imperative form of LINQ

Also: How the logic of Where no Entity Framework works?

Generics

That one TSource is a kind of super variable. It is replaced by a specific type that will be used in that data structure. This is called generic programming. It is important to study.

Func<>

This is a delegated method with a specific signature to be able to receive the code that will be used as a filter. Every time a method will be passed it is necessary to indicate his signature. Study another question about the Func<> to better understand. The predicate That’s just the name of the argument. The TSource is the type that is in the data collection to be evaluated (note that in the screenshot was used Despesa in place of TSource. The bool It is the type of return of this method, after all this method always has to answer whether the condition met or not.

IEnumerable

These methods can only be executed on objects that have the interface IEnumerable. Study her. These objects will surely have associated an iterator object to go step by step on each object element.

Yield

The algorithms are obviously different but the basic structure of all is to have a loop running through the object being processed (it has to be an enumerable) and after some processing (possibly a filter check) an element or some other result is returned.

If you return an element it is done with yield so it closes the algorithm for that element and when it comes back in it the algorithm will continue from the next element. To better understand how this works should study the yield.

Extension methods

Note that these methods give the illusion that they belong to the object, even if they are not. They are Extension methods. That’s another point to study. He uses the this seen there in the first parameter to indicate that the method can be executed as part of the object, but in the background is only passing an object to the method (nothing different from the normal methods, only in them it is "hidden" of the programmer, in extension method this is explicit).

Lambda

Usually what is passed as argument (and not parameter) for these methods are Amble (study this).

They are anonymous functions (if known JS). It is a way to create a reference to a function (the Groso mode). This reference can be saved in a variable or passed as argument. Whoever receives this reference will call this function.

So you can understand that you’re passing a function as an argument. It’s a way of giving a body to the iteration of that enumerable object.

When you pass the function instead of executing the code and passing the result, you pass the code to be executed there inside the function that will receive it.

How to read expressions lambda.

Can help: /a/99382/101

Examples

In simplified summary he makes:

public static IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> predicate) {
    foreach (T element in source) {
        if (predicate(element)) { //está chamando o código que executará a condição
            yield return element;
        }
    }

Note that this lambda has the mandatory subscription to receive an enumerable of a specific type and will return a bool, after all the result will be used in a if, has to be a boolean to make the decision. As a consumer you must know that expression must be a condition.

Reinforcement that this method will be called once, will process a single element and will close. Because of the yield it keeps the state. So when you enter the next time it will no longer run on that element, it will go to the next of the enumerable collection. It goes like this until it is closed in some way (it may have passed through all the elements).

As it returns one element at a time to keep track of this it is necessary to return the enumerator itself to keep control and be able to pass the element to other methods of LINQ, more or less as it is done with fluent interface.

The Any() does not use the yield, it does not return elements one by one, returns whether or not found:

public static bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
    foreach (T element in source) {
        if (predicate(element)) return true;
    }
    return false;
}

Already the Count() returns an integer with the count, so it has to accumulate:

public static int Count<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
    int count = 0;
    foreach (T element in source) {
        if (predicate(element)) {
            count++;
        }
    }
    return count;
}

I put in the Github for future reference.

More example of use.

Completion

You can create other methods that complement LINQ. Just follow this pattern (read how to create an extension method on link of the above section on the subject). Always will have a loop, will have to call lambda passed, almost always inside a if, but not necessarily and will have to return a final result or an element through a generator (yield). They’re not magic, special, language stuff. They are made so that any programmer with the necessary knowledge can do what they need without further complications and give better abstraction to their algorithms.

I advise researching about these terms that I passed in the answer right here at Sopt and learn more about them. I gave only the links basic. What you can’t find can be asked individually.

  • I think that’s exactly what I wanted to know, the problem is that I know so little about the subject that it has become difficult to ask a clear question rsrs. I will study upon your reply to then approve. Thank you.

6

Operation of the parameters, you find in documentation microsoft.

public static IEnumerable<TSource> Where<TSource>(
  this IEnumerable<TSource> source,
  Func<TSource, bool> predicate
)

Parameters:

  • source: Ienumerable the filtration.

  • predicate: A function to test each element for a condition.

Return value:

  • Type: System.Collections.Generic.Ienumerable

  • Ienumerable containing input sequence elements that satisfy the condition.

Type parameters:

  • Tsource: The type of source elements.

Example:

List<string> fruits =
    new List<string> { "apple", "passionfruit", "banana", "mango", 
                    "orange", "blueberry", "grape", "strawberry" };

IEnumerable<string> query = fruits.Where(fruit => fruit.Length < 6);

foreach (string fruit in query)
{
    Console.WriteLine(fruit);
}

The implementation you find on the site referencesource or Pastebin.

  • 1

    Thanks for the help, I did not know there was this "referencesource" I thought was blocked for consultation. This will help me a lot Thank you.

  • You can consult this referencesource for the Entityframework?

  • 1

    @Mauricioferraz, I don’t know if this is what you want, look at git: https://github.com/aspnet/EntityFramework

Browser other questions tagged

You are not signed in. Login or sign up in order to post.