C# study notes Lambda expression

When a delegate is instantiated, a function is always used, so we define a function separately, but more often, we don’t want to do this, but directly define the function and use it directly. At this time, an anonymous function or Lambda expression can be used. They are introduced in C#2.0 and C#3.0 respectively.

Lambda expression

Lambda expressions (or called λ expression), in fact, is a direct function of the write head and the body of the function, rather than write the function name, before the function header and function body using symbols =>to represent. And assign this function directly to a delegate or as a parameter of another function. E.g:

	MyDelegate d = (double x) => {
    
     return x + 5; };
	MyDelegate d = new MyDelegate((double x) => {
    
     return x + 5; });

Since the Lambda expression is always compatible with the delegate type, its type can be automatically inferred by the compiler, so the type of the parameter can be omitted, and only the name of the parameter variable can be written. E.g:

	MyDelegate d = (x) => {
    
     return x + 5; };

If there is only one parameter, the parentheses of the parameter can also be omitted. If there is only one return expression or one statement, the curly braces of the function can also be omitted. E.g:

	MyDelegate d = x => {
    
     return x + 5; };
	Mydelegate d = x => x + 5;

In the numerical integration of functions, DelegateLambda expressions can be used to write:

	result = Intergral(x => 2 * x + 1, 0, 1, 0.01);
	result = Intergral(x => Math.Sin(x), 0, Math.PI, 0.01);

It can be said that a Lambda expression is an embedded function, or more accurately an embedded delegate variable.

Anonymous function

An anonymous function is a function without a name. If it is assigned to the delegate immediately when the function is defined, there is no need for a name, or the compiler will automatically generate a name. In order to indicate that it is an anonymous function, a keyword must be added in front of it delegate. E.g:

	MyDelegate d = delegate (double x){
    
     return x + 5; }; 

It should be noted here: delegatehere means anonymous function, although delegatethis word can also be used to define the delegate type, but the compiler will not be confused.
Visible, Lambda expressions and anonymous function is similar, except that the use of anonymous functions delegate to represent, and Lambda expressions use =>to represent. Since Lambda can omit more, anonymous functions are rarely used now.
If there is a purpose for anonymous functions, it is that anonymous functions do not need to write parameter types and parameter names, such as:

	MyDelegate d = delegate {
    
     return 100; };

However, it is not troublesome to use Lambda expressions:

	MyDelegate d = x => 100;

Shorthand for properties and indexers

Lambda expressions (and anonymous functions) can not only simplify the writing of parameters when calling functions, but in C# 6.0 and above, they can also simplify the definition of methods, attributes, indexers and other members, called "expression body members" ( expression bodied members). E.g:

	public double Square(double n) => n * n;		// 方法
	public double Dist => Math.Sqrt(X * X + Y * Y);	// 只读属性
	public int this[int a] => members[a];			// 只读索引器

The first and second sentences define attributes and methods respectively (only get, no set).
In C#7.0 and above, you can also use more "expression body members" in construction methods, set attributes, etc., such as:

	public Person(string name) => names.TryAdd(id, name);
	public string Name{
    
    
		get => names[id];				// getters
		set => names[id] = value;		// setters
	}

3 sample programs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

class Program
{
    
    
	static void Main(string[] args) {
    
    
		Console.WriteLine("Hello World!");
		Example2();
		Console.WriteLine("---------------------分割线---------------------");
		Example3();
	}

	// 示例1, 使用线程
	private void Example1() {
    
    
		// csharp 1.0
		// 使用委托,使用已定义好的函数
		new Thread(new ThreadStart(MyFun)).Start();

		// csharp 2.0
		// 省略委托:MyFun自动实例化为ThreadStart委托
		new Thread(MyFun).Start();
		// 匿名方法
		new Thread(new ThreadStart(delegate () {
    
     Console.WriteLine("my function"); })).Start();
		// 匿名方法, 省略参数列表
		new Thread(new ThreadStart(delegate {
    
     Console.WriteLine("my function"); })).Start();
		// 匿名方法, 自动转委托
		new Thread(delegate () {
    
     Console.WriteLine("my function"); }).Start();

		// csharp 3.0
		// Lambda表达式
		new Thread(() => {
    
     Console.WriteLine("my function"); }).Start();
	}
	private void MyFun() {
    
    
		Console.WriteLine("my function");
	}


	// 示例2, 使用事件
	public class TestEventArgs
	{
    
        // 事件数据
		public string name;
		public TestEventArgs(string name) {
    
     this.name = name; }
	}
	public delegate void TestHandler(object sender, TestEventArgs e);    // 1.声明委托, 公用的
	public class TestEvent
	{
    
    
		public event TestHandler Test;  // 2.声明事件, 在一个类中
		public void UseTestEvent() {
    
     Test(this, new TestEventArgs("name")); }    // 调用事件Test
	}
	private static void Example2() {
    
    
		TestEvent testEvent = new TestEvent();

		// csharp 1.0
		// 使用委托, 使用自定义函数
		testEvent.Test += new TestHandler(TestEvent_Test);   // 3.在别的类中注册事件

		// csharp 2.0
		// 自动转委托
		testEvent.Test += TestEvent_Test;
		// 匿名方法
		testEvent.Test += new TestHandler(delegate (object sender, TestEventArgs e) {
    
     Console.WriteLine("TestEvent_Test " + e.name); });
		// 匿名方法, 自动转委托
		testEvent.Test += delegate (object sender, TestEventArgs e) {
    
     Console.WriteLine("TestEvent_Test " + e.name); };

		// csharp 3.0
		// 使用Lambda表达式
		testEvent.Test += (object sender, TestEventArgs e) => {
    
     Console.WriteLine("TestEvent_Test " + e.name); };
		testEvent.Test += (sender, e) => {
    
     Console.WriteLine("TestEvent_Test " + e.name); };

		testEvent.UseTestEvent();
	}
	private static void TestEvent_Test(object sender, TestEventArgs e) {
    
    
		Console.WriteLine("TestEvent_Test " + e.name);
	}


	// 示例3, 数组排序
	class Book
	{
    
    
		public string title;
		public double price;
		public Book(string title, double price) {
    
     this.title = title; this.price = price; }
	}
	private static void Example3() {
    
    
		Random rnd = new Random();
		Book[] books = new Book[10];
		for (int i = 0; i < books.Length; i++) books[i] = new Book("Book" + i, rnd.Next(100));
		foreach (Book book in books) Console.WriteLine(book.title + " " + book.price);
		Console.WriteLine();

		// csharp 1.0
		Array.Sort(books, new MyComparer());

		// csharp 2.0
		// 使用Comparison委托
		Array.Sort<Book>(books, new Comparison<Book>(delegate (Book book1, Book book2) {
    
     return (int)(book1.price - book2.price); }));
		Array.Sort<Book>(books, delegate (Book book1, Book book2) {
    
     return (int)(book1.price - book2.price); });

		// csharp 3.0
		Array.Sort<Book>(books, (Book book1, Book book2) => (int)(book1.price - book2.price));
		Array.Sort<Book>(books, (book1, book2) => (int)(book1.price - book2.price));   //省略参数类型

		foreach (Book book in books) Console.WriteLine(book.title + " " + book.price);


		// 使用Linq
		IOrderedEnumerable<Book> result = from book in books orderby book.price select book;

		var result1 = from book in books where book.price >= 0 orderby book.price select book.title;
		foreach (string s in result1) Console.WriteLine(s);

		var result2 = books
			.Where<Book>(b => b.price >= 0)
			.OrderBy<Book, double>(b => b.price, Comparer<double>.Default)
			.Select<Book, Book>(book => book);
		foreach (Book b in result2) Console.WriteLine(b.price + " ");

	}
	class MyComparer : System.Collections.IComparer
	{
    
    
		public int Compare(object x, object y) {
    
    
			return (int)(((Book)x).price - ((Book)y).price);
		}
	}
}

Guess you like

Origin blog.csdn.net/qq_45349225/article/details/114089860