Practical notes for learning using LinQ (2) C # enhanced features,

Source: Internet
Author: User

Practical notes for learning using LinQ (2) C # enhanced features,

C # added many language features for the support of LINQ:

  • Implicit local variables
  • Object initializer
  • Lambda expressions
  • Extension Method
  • Anonymous type

Understanding these new features is an important prerequisite for a comprehensive understanding of LINQ, so do not ignore them.

 

(1) Implicit local variables

 

The highlight of processData is {get; set;}, which is a new feature. The system automatically generatesAnonymous private variable.

 1 public Int32 Id { get; set; } 2         public Int64 Memory { get; set; } 3         public string Name { get; set; } 4  5         public processData() 6         { 7  8         } 9 10         public processData(Int32 id, Int64 mem, string name)11         {12             Id = id;13             Memory = mem;14             Name = name;15         }

 

Var eliminates the need to write two types of variables. The Compiler automatically derives the variable to effectively reduce the amount of code writing.

ObjectDumper. write () is a custom class, which is provided in the source code of this series. It can be used to conveniently display the object content.

 1   var process = new List<processData>(); 2             foreach (var m in Process.GetProcesses()) 3             { 4                 var data = new processData(); 5                 data.Id = m.Id; 6                 data.Name = m.ProcessName; 7                 data.Memory = m.WorkingSet64; 8                 process.Add(data); 9             }10             ObjectDumper.Write(process);

 

Running result:

 

(2) object initializer

 

The above code can be optimized using the constructor of the processData class.

1 // use the constructor to optimize the above Code 2 var process = new List <processData> (); 3 foreach (var m in Process. GetProcesses () 4 {5Process. Add (new processData (m. Id, m. WorkingSet64, m. ProcessName ));6} 7 ObjectDumper. Write (process );

 

The best practice is to use the object initialization tool for optimization, as shown below:

1 // use the object initialization tool to optimize the above Code 2 var process = new List <processData> (); 3 foreach (var m in Process. getProcesses () 4 {5 process. add (new processData () 6 {7 Id = m. Id, 8 Memory = m. WorkingSet64, 9 Name = m. ProcessName10}); 11} 12 ObjectDumper. Write (process );

When you knock on the above Code, click a space in {}, and the object initialization tool can also support smart sensing, which is quite convenient.

From the code above, we can see that the object initializer has many advantages:

  • Only one statement is required to initialize the object.
  • No need to provide constructors for simple objects
  • There is no need to provide multiple constructors for classes for different attributes of the implementation.

 

(3) Lambda expressions

 

To explain Lambda expressions, you must first explain the following knowledge:

  • Delegate
  • Anonymous Method

1. Delegate

C # delegation is very useful, such as updating the UI or playing a similar role as a function pointer.

The delegate function in the following example is similar to a function pointer.

 

 1         delegate bool match<T>(T obj); 2         private void disProcess(match<Process> fun) 3         { 4             var process = new List<processData>(); 5             foreach (var m in Process.GetProcesses()) 6             { 7                 if (fun(m)) 8                 { 9                     process.Add(new processData()10                     {11                         Id = m.Id,12                         Memory = m.WorkingSet64,13                         Name = m.ProcessName14                     });15                 }16             }17             ObjectDumper.Write(process);18         }19         bool filter(Process obj)20         {21             return obj.WorkingSet64 > 10 * 1024 * 1024;22         }23         private void button7_Click(object sender, EventArgs e)24         {25             disProcess(filter);26         }

 

The result is to filter process information larger than 10 MB.

 

2. Anonymous Method

The anonymous method does not need to explicitly define the method name, reducing the amount of code.

The following code omits the name of the filter function and only uses its function body code.

 

The Code improvements are as follows:

1 // demonstrate the anonymous method 2 disProcess (Delegate (Process pro) 3 {4 return pro. WorkingSet64> 10*1024*1024; 5});

 

C # added some methods in the List <T> and Array types, such as ForEach and Find, to facilitate the use of anonymous methods

Next we will modify the disProcess () function to demonstrate how to use the Find method to Find the process devenv.

1 private void disProcess (match <Process> fun) 2 {3 var process = new List <processData> (); 4 foreach (var m in Process. getProcesses () 5 {6 7 if (fun (m) 8 {9 process. add (new processData () 10 {11 Id = m. id, 12 Memory = m. workingSet64, 13 Name = m. processName14}); 15} 16} 1718 // C # added some methods in the List <T> and Array types, such as ForEach and Find, to facilitate the use of the anonymous method 19 var list1 = process. find (delegate (processData obj) 20 {21 return obj. name = "devenv"; 22 });23 24 ObjectDumper. Write (process); 25}

 

Next we can directly use Lambda expressions instead of anonymous methods.

1 // demonstrate Lambda expression 2 // read. For the input Process object, if the memory usage exceeds 10 MB, true3 disProcess (s => s. workingSet64> 10*1024*1024 );

The benefit of Lambda expressions is that there is no need to provide the parameter type, which is automatically obtained by the compiler from the method signature.

In addition to implementing the anonymous method function, Lambda also provides additional benefits:

  • No parameter type required
  • The statement block or expression can be used as the method body. The anonymous method can only use the statement block.
  • Supports selecting overload functions through Parameters
  • A Lambda expression with an expression body can be converted to an Expression Tree.

 

(4) Extension Method

The following example shows how to find a process that occupies more than 10 MB, and convert it to MB.

Compared with the common method, if the extension method is used for implementation, its syntax structure makes it easy for programmers to concatenate many operations.

In this way, the actual execution sequence and reading sequence of the Code are completely consistent with the human thinking.

On the other hand, the extension method is supported by smart sensing. You can quickly find the extension method after you type it.

 

 

 

1 private void button10_Click (object sender, EventArgs e) 2 {3 // Let's write three extension methods and execute them in order. Expected result 4/1 is displayed. filterOutSomeProcess () filters out some qualified processes. 5 // 2. totalMemory (): the total memory usage of these processes is 6 // 3. bytesToMegaBytes () converts the memory usage to MB, which means 7 8 // searches for processes with an internal usage greater than 10 MB. The total computing memory usage is changed to MB. 9 Console. writeLine ("searches for processes that occupy more than 10 MB of memory internally, and converts the total computing memory usage to MB." 10 + Environment. newLine); 11 Console. writeLine (12 Process. GetProcesses () 13. FilterOutSomeProcess (filter2) 14. TotalMemory () 15. BytesToMegaBytes () + "MB"16); 17} 1819 bool filter2 (long mem) 20 {21 if (mem> 10*1024*1024) return true; 22 return false; 23}

 

The following is the definition of the above three extension methods.

As you can see, the extension method adds the keyword this before the type of the class to be extended. The others are no different from the general method.

In intelligent sensing, the extension method icon has a small arrow down to distinguish it from a common method.

 1  delegate bool filterDelegate(long mem); 2     static class externFun 3     { 4         public static List<processData> FilterOutSomeProcess(this Process[] pro,filterDelegate fun) 5         { 6             var proList = new List<processData>(); 7             foreach (var m in pro) 8             { 9                 if(fun(m.WorkingSet64))10                     proList.Add(new processData()11                     {12                         Id = m.Id,13                         Memory = m.WorkingSet64,14                         Name = m.ProcessName15                     });16             }17             return proList;18         }19 20         public static long TotalMemory(this List<processData> data)21         {22             long sum=0;23             data.ForEach(s => sum += s.Memory);24             return sum;25         }26 27         public static float BytesToMegaBytes(this long sum)28         {29             return (float)sum / 1024f / 1024f;30         }31 32     }

 

The result is as follows:

 

LINQ also brings about a series of extension methods. They can also be not used in LINQ. Use them to include using System. Linq

Below we will introduce several:

OrderByDescending

Take

Sum

 

We use an example to introduce the above three extension methods.

In this example, the process is sorted by memory usage. The first two memory-consuming large instances are used to calculate the total memory they consumed, expressed in MB.

1 private void button11_Click (object sender, EventArgs e) 2 {3 var list1 = new List <processData> (); 4 foreach (var m in Process. getProcesses () 5 {6 list1.Add (new processData () 7 {8 Id = m. id, 9 Memory = m. workingSet64, 10 Name = m. processName11}); 12} 13 Console. writeLine ("processes are sorted by memory usage. Take the first two memory-consuming large households and calculate the total memory they consumed, expressed in MB" + 14 Environment. newLine); 15 Console. writeLine (16 list117. OrderByDescending (s => s. Memory) 18. Take (2) 19. Sum (s => s. Memory)/1024f/1024f + "MB"20); 21}

 

Description of the extension method:

1. The extension method must be defined as a static class and should be public or static.

2. If the instance method and the extension method have the same name, run the instance method first. The extension method has a lower priority.

3. The extension method cannot access non-public members of the type.

 

(5) Anonymous type

 

With the anonymous type, we can do the same without using the processData class defined above.

 

1 private void button12_Click (object sender, EventArgs e) 2 {3 var list1 = new List <Object> (); 4 foreach (var m in Process. getProcesses () 5 {6 // you do not need to specify the attribute name for the anonymous type. The attribute name is only used to make the Code better understand 7 list1.Add (8New 9 {10 // Id = m. id, 11 // Memory = m. workingSet64, 12 // Name = m. processName13 m. id, 14 m. workingSet64, 15 m. processName16 });17} 18 ObjectDumper. Write (list1); 19 2021 var obj = ReturnAGeneric () => new22 {23 Time = DateTime. now, 24 Name = "hackpig" 25}); 26 // the following code is invalid because an anonymous instance is unchangeable and does not have set27 // obj. name = "lxy1"; 28 // obj. time = DateTime. now; 29 ObjectDumper. write (obj );30 31} 3233 public static TResult ReturnAGeneric <TResult> (Func <TResult> creator) 34 {35 return creator (); 36}

The advantage of the anonymous type is that you do not need to write special types to store the temporary data, which can greatly speed up program writing.

There are some restrictions on the anonymous type, as follows:

  • To operate an anonymous type other than a method that defines an anonymous type, only reflection is required.
  • The anonymous type is only suitable for storing temporary data and cannot be used as a method return type (except for methods that return values in the generic type)
  • Once an instance is created for the anonymous type, the value of the instance is fixed and unchangeable, that is, the instance cannot be set again. the reason for this restriction is to serve the value-based programming style of functional programming to avoid unnecessary side effects. in addition, in PLINQ, this feature is crucial. objects that will never change greatly reduce the difficulty of concurrent processing in programming.

 

The contents of the first two chapters of this book have ended. I feel that the explanation is quite brilliant.

The following is the source code of the exercise. Some of these codes are different from those of the Source Book and are adapted based on understanding.

 

Source code

 

Original article, from "blog garden, pig weneng's blog": http://www.cnblogs.com/hackpig/

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.