O estudo C # observa a expressão lambda

Quando um delegado é instanciado, uma função é sempre usada, então definimos uma função separadamente, mas mais frequentemente, não queremos fazer isso, mas definir diretamente a função e usá-la diretamente. Neste momento, uma função anônima ou Pode-se usar a expressão lambda, introduzida em C # 2.0 e C # 3.0, respectivamente.

Expressão lambda

As expressões lambda (ou denominadas expressão λ), na verdade, são uma função direta do cabeçalho de gravação e do corpo da função, em vez de escrever o nome da função, antes do cabeçalho da função e do corpo da função usando símbolos =>para representar. E atribua esta função diretamente a um delegado ou como parâmetro de outra função. Por exemplo:

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

Como a expressão Lambda é sempre compatível com o tipo de delegado, seu tipo pode ser inferido automaticamente pelo compilador, portanto, o tipo do parâmetro pode ser omitido e apenas o nome da variável do parâmetro pode ser escrito. Por exemplo:

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

Se houver apenas um parâmetro, os parênteses do parâmetro também podem ser omitidos. Se houver apenas uma expressão de retorno ou uma instrução, as chaves da função também podem ser omitidas. Por exemplo:

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

Na integração numérica de funções, as Delegateexpressões Lambda podem ser usadas para escrever:

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

Pode-se dizer que uma expressão Lambda é uma função incorporada ou, mais precisamente, uma variável delegada incorporada.

Função anônima

Uma função anônima é uma função sem um nome. Se for atribuída ao delegado imediatamente quando a função for definida, não há necessidade de um nome, ou o compilador irá gerar um nome automaticamente. Para indicar que é uma função anônima, uma palavra-chave deve ser adicionada antes dela delegate. Por exemplo:

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

Deve-se notar aqui: delegateaqui significa função anônima, embora delegateesta palavra também possa ser usada para definir o tipo de delegado, mas o compilador não será confundido.
Visível, as expressões Lambda e a função anônima são semelhantes, exceto que o uso de funções anônimas delegam para representar e as expressões Lambda usam =>para representar. Como o Lambda pode omitir mais, as funções anônimas raramente são usadas agora.
Se houver uma finalidade para funções anônimas, é que as funções anônimas não precisam escrever tipos de parâmetros e nomes de parâmetros, como:

	MyDelegate d = delegate {
    
     return 100; };

No entanto, não é problemático usar expressões Lambda:

	MyDelegate d = x => 100;

Abreviação de propriedades e indexadores

Expressões lambda (e funções anônimas) podem não apenas simplificar a escrita de parâmetros ao chamar funções, mas em C # 6.0 e superior, elas também podem simplificar a definição de métodos, atributos, indexadores e outros membros, chamados de "membros do corpo da expressão" (expressão membros corporais). Por exemplo:

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

A primeira e a segunda frases definem atributos e métodos respectivamente (apenas get, não set).
No C # 7.0 e superior, você também pode usar mais "membros do corpo de expressão" em métodos de construção, definir atributos, etc., como:

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

3 programas de amostra:

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);
		}
	}
}

Acho que você gosta

Origin blog.csdn.net/qq_45349225/article/details/114089860
Recomendado
Clasificación