C#スタディノートラムダ式

デリゲートがインスタンス化されると、関数が常に使用されるため、関数を個別に定義しますが、多くの場合、これを実行したくないが、関数を直接定義して直接使用します。現時点では、無名関数またはラムダ式を使用できます。それぞれC#2.0とC#3.0で導入されています。

ラムダ式

ラムダ式(またはλ式と呼ばれる)は、実際には、関数のヘッダーと関数本体の前に、記号=>使用して表すために、関数名を書き込むのではなく、書き込みヘッドと関数の本体の直接関数ですそして、この関数をデリゲートに直接割り当てるか、別の関数のパラメーターとして割り当てます。例えば:

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

Lambda式は常にデリゲート型と互換性があるため、その型はコンパイラーによって自動的に推測されるため、パラメーターの型は省略でき、パラメーター変数の名前のみを書き込むことができます。例えば:

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

パラメーターが1つしかない場合は、パラメーターの括弧も省略できます。戻り式またはステートメントが1つしかない場合は、関数の中括弧も省略できます。例えば:

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

関数の数値積分では、Delegateラムダ式使用して次のように記述できます

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

Lambda式は埋め込み関数、より正確には埋め込みデリゲート変数であると言えます。

匿名関数

匿名関数は名前のない関数です。関数が定義された直後にデリゲートに割り当てられる場合、名前は必要ありません。そうでない場合、コンパイラは自動的に名前を生成します。これが無名関数であることを示すには、その前にキーワードを追加する必要がありますdelegate例えば:

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

ここで注意する必要があります。delegateここでは無名関数を意味しますが、delegateこの単語はデリゲートタイプの定義にも使用できますが、コンパイラーが混乱することはありません。
Visible、Lambda式と無名関数は似ていますが、無名関数を使用=>して表現するように委任し、Lambda式を使用して表現する点が異なります。Lambdaはさらに省略できるため、匿名関数は現在ほとんど使用されていません。
匿名関数の目的がある場合、匿名関数は次のようなパラメータータイプとパラメーター名を記述する必要がないということです。

	MyDelegate d = delegate {
    
     return 100; };

ただし、Lambda式を使用するのは面倒ではありません。

	MyDelegate d = x => 100;

プロパティとインデクサーの省略形

ラムダ式(および無名関数)は、関数を呼び出すときのパラメーターの記述を簡素化できるだけでなく、C#6.0以降では、メソッド、属性、インデクサー、および「式本体メンバー」(式)と呼ばれるその他のメンバーの定義も簡素化できます。ボディメンバー)。例えば:

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

最初の文と2番目の文は、それぞれ属性とメソッドを定義します(のみget、いいえset)。
C#7.0以降では、次のように、構築メソッドでより多くの「式本体メンバー」を使用したり、属性を設定したりすることもできます。

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

3つのサンプルプログラム:

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

おすすめ

転載: blog.csdn.net/qq_45349225/article/details/114089860