提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
C# Lambda表达式
此总结是参考C#图解教程总结而来的,仅供参考
前言
C# Lambda 作用
Lambda表达式可用于简化C#中委托的匿名语法
我们通过使用Lambda表达式前后委托的语法做比较
一、使用Lambda 之前的示例
此示例为委托的匿名方法声明不带Lambda表达式
namespace ConsoleApp3
{
class Program
{
//委托字段--带输入参数X
public delegate void CountAdd(int x);
static void Main(string[] args)
{
int y = 2;
//委托的匿名声明--注意在delegate后面添加参数X
CountAdd CountAdd1 = delegate (int x)
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
CountAdd1(y);
}
}
}
以上代码输出内容为:
Before add the y value is 2
the add value is 3
二、使用Lambda 之后的示例
namespace ConsoleApp3
{
class Program
{
public delegate void CountAdd(int x);
static void Main(string[] args)
{
int y = 2;
//此处为未使用Lambda表达式的语法
CountAdd CountAdd1 = delegate (int x)
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
//CountAdd1(y);
//此处为使用了Lambda表达式的语法, 在此语法中将声明的关键字delegate取消并在参数之后添加=>Lambda符号
CountAdd CountAdd2 = (int x) =>
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
CountAdd2(y);
}
}
}
以上代码输出内容为:
Before add the y value is 2
the add value is 3
然而Lambda可以将表达式更精简…
在以上Lambda示例中我们利用Lambda表达式简化了原有的"delegate"关键字,并添加了=>字符,这似乎并没有什么太大的变化,实际上我们可以进一步简化,在以下2个方面进行
- 简化其输入参数将其显示类型变为隐式类型
- 带有类型的参数列表称为显式类型
- 省略类型的参数列表称为隐式类型
- 注意如果在Lambda表达式中有ref或out类型则必须注明参数类型
- 在只有一个隐式类型输入参数的情况下可以将输送参数两边的圆括号省略
- 简化代码块两边的中括号最后,Lambda 表达式允许表达式的主体是语句块或表达式,如果 语句 块包含了一个返回语句,我们可以将语句块替换为return关键字后的表达式
来看示例:
namespace ConsoleApp3
{
class Program
{
public delegate void CountAdd(int x);
static void Main(string[] args)
{
int y = 2;
//不带Lambda 表达式的委托匿名语法声明
CountAdd CountAdd1 = delegate (int x)
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
//CountAdd1(y);
//简化了"delegate"的Lambda表达式声明
CountAdd CountAdd2 = (int x) =>
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
//CountAdd2(y);
//简化了输入参数及其两边括号的Lambda表达式声明
CountAdd CountAdd3 = x =>
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
CountAdd3(y);
}
}
}
以上代码输出内容为:
Before add the y value is 2
the add value is 3
另外两种Lambda表达式简化语法
- 当Lambda表达式只有一个表达式时其两边的中括号可以省略
看下面的示例:
namespace ConsoleApp3
{
class Program
{
public delegate void CountAdd(int x);
static void Main(string[] args)
{
int y = 2;
CountAdd CountAdd3 = x =>
{
x += 1;
Console.WriteLine("Before add the y value is {0}", y);
Console.WriteLine("the add value is {0}", x);
};
//当CountAdd4的Lambda表达式只包含一个表达式时其两边的中括号可以省略掉
//CountAdd CountAdd4 = x =>{CountAdd3(x);};
CountAdd CountAdd4 = x => CountAdd3(x);
CountAdd4(y);
}
}
}
以上代码输出内容为:
Before add the y value is 2
the add value is 3
- 当Lambda表达式中包含一个返回语句时,可以将其替换为return后的语句
看下面的示例:
namespace ConsoleApp3
{
class Program
{
public delegate int CountAddReturn(int x);
static void Main(string[] args)
{
int y = 2;
//当Lambda语句中只有一个Return语句时可将其替换成Return后的内容
//CountAddReturn CountAdd5 = x => { return x + 1; };
CountAddReturn CountAdd5 = x => x + 1;
Console.WriteLine("The CountAdd5 return value is {0}", CountAdd5(y));
}
}
}
以上代码输出内容为:
The CountAdd5 return value is 3
三、WPF 中标题为按钮添加异步方法
新建WPF项目并添加如下XAML程序
<Window x:Class="WpfApp_Lamda.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp_Lamda"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock Name="workStartedTextBlock" Margin=" 10, 10"/>
<Button Name="startWorkButton" Width=" 100" Margin=" 4" Content=" Start Work" />
</StackPanel>
</Window>
在cs程序中利用async/await特性为按钮添加如下程序,实现当点击按钮后触发的事件在异步执行,主线程的操作如调整窗口大小及移动仍能正常执行,否则在没有异步的情况下主线程会等待4s的时间才能响应用户操作,这显然是不能接受的。
namespace WpfApp_Lamda
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//Lamda 异步方法声明委托
startWorkButton.Click += async (sender,e) =>
{
SetGuiValues(false, "Work Started");
await DoSomeWork();
SetGuiValues(true, "Work Finished");
};
}
private void SetGuiValues(bool buttonEnabled, string status)
{
startWorkButton.IsEnabled = buttonEnabled;
workStartedTextBlock.Text = status;
}
private Task DoSomeWork()
{
return Task.Delay(4000);
}
}
}
总结
- Lambda表达式是对匿名语法的简化可供了解,在阅读代码时可识别语句
- Lambda表达式声明仍需要保持与委托的声明参数数量、类型及位置上保持一致
- Lambda表达式中如果只有一个参数并且可声明为隐式类型的情况下其两边的圆括号可以省略
- Lambda表达式中如果语句中只有一个表达式时可以省略其两边的大括号
- Lambad表达式中如果没有参数则圆括号不能省略