C ා basic knowledge series - 6 brief introduction to lambda expression and Linq

Preface

C's lambda and Linq can be said to be a bright spot. C's lambda is everywhere. Linq also plays an important role in data query.

So what is Linq? Linq is the abbreviation of language integrated query, which can perform structured query operations on local object collections or remote data sources.

So what is lambda? Well, in short, it's an anonymous function. We don't declare a method name, but write a method body, which is a lambda expression

lambda expressions

How to write a lambda expression

First, before you write a lambda expression, you need to understand two special types: Func and Action.

These are two delegates. We don't need to know what a delegate is. We can treat them as a name specification. They can both represent a method. The difference is that Func represents a method with return value and Action represents a method without return value. C. The definitions of these two are as follows:

public delegate TResult Func<out TResult>();//Note that the out here indicates that the generic is the type generic of the return value
public delegate void Action();

There are 16 variants of Func and Action respectively:

// Note the in keyword, indicating that generics are type constraints of parameters
public delegate TResult Func<in T,out TResult>(T arg);
public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2);
......
public delegate TResult Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16,out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
//
//

public delegate void Action<in T>(T obj);
public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);
......
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);

One parameter, two parameters Sixteen parameter method. Of course, you can write more parameters, but if there are more than 10 parameters in a method, why not use class encapsulation? Even if you don't encapsulate a method with more than ten parameters, are you sure you won't be rejected by your leaders.

To get back to the point, I've introduced the definitions of Func and Action. What if I use them?

public void Demo1()
{
    // A method with no return value and no parameters
}

Action act1 = Demo;// Give a method name directly

public void Demo2(string name)
{
    //There is a parameter but no method to return a value
}

Action<string> act2 = Demo2;

public String Demo3()
{
    // Method with return value but no parameter
}
Func<string> func1 = Demo3;

public int Demo4(double data)
{
    // The return value is int, and there is a method with a double parameter
}

Func<double,int> func2 = Demo4;


The above method is to get Func and Action by method name. The following describes how to create Func and Action by Lambda expression:

Action act1 = ()=> // Symbolic declaration of lambda = >
{
	// This is a lambda expression with no return value and no parameters
};
Action<int> act2 = (age) => 
{
    // This is a lambda expression with an int parameter and no return value
};
//=========================================
Func<string> func1 = () => ""; // This is a lambda expression that returns an empty string. Note this
Func<string> func2 = () =>
{
    return ""; //Equivalent to previous
}

Func<int,string> func3 = (age) =>
{
    return "My age is:"+age;// One parameter is int, and the return type is a lambda expression of string
}

In a lambda expression, when a method body with return value is used, if the method body is a simple formula or can be written in one line (or considered as one line by the compiler), then {,} and return can be omitted and marked with = > directly.

For example:

Func<int,int,int> cal_area = (width, height) => width * height;// Calculated area

Using Lambda expressions

Now we have a lot of actions and Func S in our hands. How can we use them?

There are two common uses:

  1. Use it as a method:

    // Code above
    act1();// Execute the method or lambda expression represented by act1
    act2(10); //Execute the lambda expression of act2
    
    string str1 = func1();
    string str2 = func3(10);
    int area = cal_area(29,39);
    
  2. Call Invoke method:

    act1.Invoke();
    act2.Invoke(10);
    
    area = cal_area.Invoke(33,63);
    

    Those who have read the reflection should have a certain impression on the Invoke, which is similar to the Invoke in MethodInfo, but simpler than it.

What is Linq

As mentioned in the foreword, Linq is an integrated query method for collection and data source. It is an extended method set for IEnumerable < T >. Therefore, to use Linq, you need to refer to two namespaces System.Linq and System.Linq.Expressions.

Linq can be used in two ways: one is to call through method chain, and the other is to query data similar to SQL statement. The method chain is the foundation, and the SQL like method is the syntax sugar. Here is a brief introduction to the use of the two methods. First, let's assume that we have a collection with a lot of data:

IEnumerable<int> scores = new List<int>();//Suppose you have 50 Chinese scores in a class

Use method chain query

  1. Get all scores with scores greater than 60:

    IEnumerable<int> result1 = scores.Where(t => t > 60);
    
  2. Get number with score greater than or equal to 60:

    int count = scores.Count(t => t >= 60);
    
  3. Total score

    int sum = scores.Sum();
    
  4. Get the number on all score bits:

    IEnumerable<int> result2 = scores.Select(t => t % 10);
    

Using SQL like queries

Query all scores greater than or equal to 60:

IEnumerable<int> result3 = from score in scores
                where score >= 60
                select score;

For a brief introduction, there is a unified format writing method for SQL like forms, and the keywords from, in, and select are indispensable:

from temporary variable name in data source

select result type

where is conditional filtering. If the query is all, it can be ignored.

The reason why I call this method SQL like form is that its writing method is similar to SQL, and those who are familiar with SQL can start quickly.

Why is the method chain the foundation?

Because there is a method behind every keyword in SQL queries, except from and in.

Select corresponding select method, where corresponding where method.

One special note:

Linq query is a kind of delayed query, that is to say, when the return type is an IEnumerable, the result will not be returned immediately. You must call ToList to get the actual query result. In addition, it should be noted that ToList returns an immutable List collection, which is described in the collection chapter.

To be continued

Linq in C Chen is so rich that it can't be explained in detail for a while. There will be two or three articles about Linq in the future. I'll be here today. Thank you for reading.

Please pay attention to more My blog

Tags: C# Lambda SQL

Posted on Thu, 02 Apr 2020 09:17:02 -0700 by Teen0724