[.net Basics of Object-Oriented Programming] (18) Basics of LINQ

This article is transferred from: https://www.cnblogs.com/yubinfeng/p/4570688.html

   In the last two sections we introduced .net arrays, collections and generics. We said that arrays are a reference type that extends from the previous programming language, and the storage area is allocated by defining the length in advance. The collection is designed for the convenience of data set retrieval in the early .Net version. It has the advantage over arrays. In addition to the convenience of retrieval, it can also automatically allocate storage areas during use without the need to define the size in advance. However, the collection has performance problems caused by unsafe types and frequent boxing and unboxing operations. Generics are designed after .net 2.0 to solve the defects of collections, and adopt the method of declaring the type at the instance call stage, which solves the security problem and the efficiency problem. 

With the development of .net 3.5 and later versions, Microsoft designed LINQ to make our retrieval more convenient and development more efficient. 

1. LINQ concept 

LINQ, Language Integrated Query is a set of extensions for c # and Visual Basic language. It allows writing C # or Visual Basic code to manipulate memory data in the same way as querying the database. 

The above is the definition from Baidu Encyclopedia. 

Through the English name description, we can see that it is a solution that allows developers to retrieve memory data like querying a database. 

2. Before learning LINQ, you need to master the following knowledge points

It looks a bit more, but all of them are the basics of learning LINQ. We said that LINQ is to manipulate memory data like SQL statements. Then to learn SQL, you must master the basic concepts of tables, fields, and views. LINQ is also the same. 

2.1 Implicit types 

Before we defined a variable, we needed to specify a type, and foreach traversal, we also specified the type. With the emergence of implicit types, we no longer need to do this work, but use var definitions, which is more like a weakly typed language such as javascipt. But .NET is not a weakly typed language, the definition of implicit types is written as follows: 

var i = 1; 
var b = "xyz"; 
var obj = new MyObj ();

The above implicit type is equivalent to 

int i=1;
string b=”xyz”;
MyObj obj=new MyObj();

A few notes about implicit types: 

A. With implicit types, you can use var to define any type of variable in coding 

B. Implicit types do not affect program performance. .NET will help us convert to specific data types at compile time. Therefore, we must assign values ​​when declaring implicit types. Otherwise, .NET cannot judge what type is converted to an error.

C. Implicitly typed var saves us a lot of time in development. When defining a variable, the type needs to be lost twice, and var is done in one click. You can also use var to write the type of loop variable during the foreach traversal. 

2.2 Anonymous type 

We new an object, the elements and types in it can be declared anonymously, but anonymously. as follows: 

Copy code
//匿名类型
var obj =new  { str = "abc", Guid.Empty,myArray = new int[] { 1, 2, 3 } };
Console.WriteLine(obj.str);
Console.WriteLine(obj.Empty);
Console.WriteLine(obj.myArray[0]);
Console.ReadLine();
Copy code

 The results are as follows:

After we see an object in new, we automatically define properties for the object and assign values ​​to these properties. When copying the properties of an object to an anonymous object, we do n’t need to display the name of the specified property. At this time, the name of the original property will be Be "copied" to anonymous objects. As shown below:

 

The obj.Empty property name is automatically created.
If you monitor the variable obj, you will find that the type of obj is of type Anonymous Type.
Don't try to access the properties of an object outside the method of creating an anonymous object!
This feature is useful for serializing and deserializing JSON objects in website development.

2.3 Automatic attributes

Remember that in the "Refactoring" section, we talked about the refactoring of attributes. We only need to use the "encapsulated fields" provided by vs.net on the field names to generate the corresponding attributes for us, as shown below:

 

(figure 1)


(figure 2)

(image 3)

Since .net 3.0, our code can be written more simply, the code is as follows: 

// Automatic attribute 
class Flower { 
    public string Leaf {get; set;} 
    public string Name {get; set;} 
}

Refactoring is of course only an auxiliary function of .net. For automatic attribute friends, we will definitely worry about the efficiency of this writing. This can be assured. Like var implicit type, .net will help us write the complete , Without any performance issues.

2.4 Initializer

For the initialization of an object, suppose there are the following two objects:

Copy code
//初始化器
class Flower {
    public string Leaf{get;set;}
    public string Name{get;set;}
}

class Bear
{
    public Bear(string name){}
    public string Name { get; set; }
    public double Weight { get; set; }

}
Copy code

In versions prior to 3.0, we are generally similar to the following:

// 
Initiator 
Flower flower = new Flower (); flower.Leaf = "leaf"; 
flower.Name = "cotton";

In versions after 3.0, we can write:

Copy code
// Object initialization after .net 3.0 can be written as follows 
Flower flower2 = new Flower () {Name = "桃花", Leaf = "桃叶"}; 
// Initialize the constructor with parameter object 
Bear bear = new Bear ("polar bear" ) {Name = "熊熊", Weight = 300}; 
// Set initialization 
var array = new List <char> () {'a', 'b', 'c', 'd', 'e', ​​'f '};
Copy code

We can see that the writing is much simpler and better. Especially the assignment to generic collections is quite concise and clear.

2.5 Anonymous method

When it comes to anonymous methods, it means that when you delegate a method, you can write the method in the delegate statement. Simply put, you do n’t have to write the method separately. Before talking about this, we originally wanted to introduce delegation, but in the next section, we will focus on explaining delegation. Here we only need to understand the anonymous method. Let's look at an example: 

Copy code
1 // delegate function 
 2 Func <int, int, string> func1 = Adds; 
 3 // anonymous method 
 4 Func <int, int, string> func2 = 
 5 delegate (int a, int b) 
 6 { 
 7 return a + "+ "+ b +" is equal to how many? "+ Environment.NewLine + (a + b) .ToString (); 
 8}; 
 9 // Lambda expression 
10 Func <int, int, string> func3 = 
11 (a, b) = > {return a + "+" + b + "What is equal to?" + Environment.NewLine + (a + b) .ToString ();}; 
12 
13 // Call the Func delegate 
14 string sum = func2 (45, 36) ; 
15 
16 Console.WriteLine (sum); 
17 Console.ReadLine ();
Copy code
// Delegation method 
static string Adds (int a, int b) 
{ 
    return a + "+" + b + "What is equal to?" + Environment.NewLine + (a + b) .ToString (); 
}

By using anonymous methods, you can access the variables in the context. In the case where the method itself is not very long, lightweight writing is very practical.

This is specified in the entrustment in the next section. It does n’t matter if your friends do n’t understand it here. 

2.6 Extension methods

1) The extension method is declared in a static class, defined as a static method, and its first parameter needs to be identified with the this keyword to indicate the type it extends.

2) Extension methods can write methods into classes that did not initially provide the method. You can also add methods to any class that implements an interface so that multiple classes can use the same implementation code. (In LINQ, System.Linq.Queryable.cs and System.Linq.Enumerable.cs add extension methods to the interface)

3) Although the extension method is defined as a static method, it does not need to provide the name of the class that defines the static method when it is called. It only needs to introduce the corresponding namespace and the access method is the same as the instance method.

4) The extension method cannot access the private members of the type it extends.

example:

Copy code
public static IEnumerable<TSource> MyWhere<TSource>(
    this IEnumerable<TSource> source, Func<TSource, bool> predicate)
 {
            foreach (TSource item in source)
            {
                if (predicate(item))
                    yield return item;
            }
}
Copy code

 Let's take a look at the power of extension methods. To add behavior to a type, you don't have to use inherited methods. You can also write this:

var a = "aaa";
a.PrintString(); 
Console.ReadKey();

But through our code above, a PrintString method is "extended" to the string type.

(1) Prerequisites

<1> The extension method must be defined in a non-nested, non-generic static class

<2> The extension method must be a static method

<3> The extension method must have at least one parameter

<4> The first parameter must be prefixed with this keyword

<5> The first parameter cannot have other modifiers (such as ref or out)

<6> The first parameter cannot be a pointer type

(2) Precautions

<1> Like several features mentioned above, the extension method will only increase the work of the compiler, and will not affect the performance (adding features to a type by inheritance will affect the performance)

 <2> If there is a method in the original class, which is the same as your extension method (at least it is the same), then your extension method award will not be called, and the compiler will not prompt you

 <3> The extension method is too powerful, which will affect the architecture, mode, readability, etc ...

2.7 Iterator

(1) Use

Every time we write a foreach code block for a collection type, we are using iterators

These collection types implement the IEnumerable interface

There is a GetEnumerator method

But this is not the case for array types

The compiler puts the foreach code block for the array type

Replaced with for code block.

Let's take a look at the type signature of List: 

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

IEnumerable interface, only one method is defined:   

IEnumerator<T> GetEnumerator();

(2 ) The advantages of iterator :

 Suppose we need to traverse a huge collection

 As long as a certain element in the set meets the condition

 Completed the task

 Do you think you need to load this huge collection into memory?

 Of course not (not after C # 3.0)!

 Let's take a look at this code:         

Copy code
static IEnumerable <int> GetIterator () 
{ 
    Console.WriteLine ("Iterator returned 1"); 
    yield return 1; 
    Console.WriteLine ("Iterator returned 2"); 
    yield return 2; 
    Console.WriteLine ("Iterator Returned 3 "); 
    yield return 3; 
}
Copy code
Copy code
foreach (var i in GetIterator())
{
    if (i == 2)
    {
        break;
    }
    Console.WriteLine(i);
}
Console.ReadKey();
Copy code

The output is:    

Iterator returns 1 

1 

Iterator returns 2

You can see:

When the iterator returns 2, foreach exits

And did not output "Iterator returned 3"

In other words, the following work is not done.

(3) Yield keywords

The explanation in MSDN is as follows:

Used in iterator blocks to provide values ​​to enumerator objects or to signal the end of iterations.

In other words, we can determine when to terminate the iteration logic when generating an iterator

The above code can be changed to the following form:  

Copy code
static IEnumerable <int> GetIterator () 
{ 
    Console.WriteLine ("Iterator returned 1"); 
    yield return 1; 
    Console.WriteLine ("Iterator returned 2"); 
    yield break; 
    Console.WriteLine ("Iterator returned 3 "); 
    yield return 3; 
}
Copy code

(4) Precautions

<1> Consider thread safety when doing foreach loop      

Don't try to remove and add operations on the traversed collection during foreach

Any collection, even if it is marked as thread-safe, when foreach, adding and removing items will cause an exception

<2> The IEnumerable interface is the core interface of LINQ features

Only collections that implement the IEnumerable interface

To perform relevant LINQ operations, such as select, where, etc.

About the specific operation of LINQ, the next section inherits.

2.8 Lambda expressions

Lambda expressions simply write anonymous methods in a simpler way, which completely simplifies the use of .NET delegate types.  

Lambda expressions are written in C # as "arg-list => expr-body". The left side of the "=>" symbol is the expression parameter list, and the right side is the expression body (body). The parameter list can contain 0 or more parameters, separated by commas.

Through the above anonymous method example, we can see that the following two pieces of code are equivalent:

Copy code
// Anonymous method 
Func <int, int, string> func2 = 
    delegate (int a, int b) 
    { 
        return a + "+" + b + "is equal to?" + Environment.NewLine + (a + b) .ToString (); 
    }; 
// Lambda expression 
Func <int, int, string> func3 = 
    (a, b) => {return a + "+" + b + "equal to?" + Environment.NewLine + (a + b). ToString ();};
Copy code

Lambda expressions are named based on the lambda (11th letter of Greece) calculus in mathematics, and "lambda expression" refers to writing anonymous methods in a simple way.

3. Key points:

A. LINQ, Language Integrated Query (Language Integrated Query ) is a language extension that allows us to manipulate memory data (collections, etc.) like querying a database.

B. Anonymous type: When using new to declare an anonymous type, you do not need to specify the type. For .NET 3.0 and later, you can automatically complete the type assignment and attribute name assignment.

C. Automatic attributes: In .net 3.0 and later versions, we define the attributes and only need to write get; set; simply. .Net will help us complete the writing during the compilation phase, and there will be no performance problems.

D. Initializer: In versions after 3.0, it is easier to write object initialization, especially the assignment of generic collections, which is quite concise and clear.

E. Anonymous method: When delegating a method, there is no need to specify the method name. Using an anonymous method can access the variables in the context. In the case of less method code, it is very practical to implement delegation at a light weight.

F. Extension method: you can add behavior to a type without using inheritance

G. Iterator: When traversing a huge collection, you do not need to load it all in memory, as long as the conditions are met, you can return.

H. Lambda expressions: Lambda expressions are named based on the λ (the 11th letter of Greece) calculus in mathematics, and "Lambda expressions" (lambda expressions) refer to writing anonymous methods in a simple way .

Remarks: This article refers to some articles from bloggers. There are a large number of them, and they are not listed one by one. Thank you here.

For the use of LINQ, we will explain in detail in the next section. 

Guess you like

Origin www.cnblogs.com/hanguoshun/p/12728452.html