目录

匿名函数,lambda表达式

1.匿名函数

匿名函数是没有名称的函数,它们可以直接在代码中声明和使用。C#中的匿名函数有两种形式:委托匿名函数lambda表达式

委托匿名函数

Func<int, int, int> add = delegate(int a, int b)
{
    return a + b;
}
Console.WriteLine(add(2, 3)); // 输出 5

Lambda表达式

Lambda表达式是匿名函数的一种简化形式,语法更为简洁。它使用 => 运算符,左边是参数,右边是表达式或代码块。

Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(2, 3)); // 输出 5

2.Lambda表达式

Lambda表达式的语法非常简洁,它可以用来表达内联方法或传递行为。它可以省略一些类型的声明,C#会根据上下文自动推断。

常用方法

  • 表达式主体:用于简短的返回表达式。

    Func<int, int, int> add = (a, b) => a + b;
  • 语句主体:如果需要多个语句,可以使用代码块。

    Action<string> printMessage = message =>
    {
     	Console.WriteLine("Message: " + message);
        Console.WriteLine("Length: " + message.Length);
    }
    printMessage("Hello Lambda!");

3.在WPF中的简单使用

在WPF中,匿名函数和lambda表达式通常被用于以下几种场景:

  • 事件处理:可以用lambda表达式简化事件处理代码。
  • 数据绑定:在某些情况下,可以使用lambda表达式进行数据转换。
  • 命令绑定:WPF中的命令绑定也可以用lambda表达式。

事件处理示例

假设我们有一个按钮,点击按钮时改变Label的内容。我们可以使用lambda表达式简化事件处理:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Lambda Expression Demo"
        Height="350"
        Width="525">
    <Grid>
        <Button Name="myButton" Content="Click Me" VerticalAligment="Top"
                HorizontalAligment="Left" Width="100" Height="50" 
                Click="myButton_Click"/>
        <Label Name="myLabel" VerticalAligment="Top" HorizontalAligment="Left"
              Margin="0,60,0,0"/> 
    </Grid>
</Window>
using System.Windows;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // 使用lambda表达式绑定Click事件
            myButton.Click += (sender, e) => myLabel.Content = "Button Clicked!";
        }
        
        // 传统的事件处理方式
        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            myLabel.Content = "Button Clicked!";
        }
    }
}

数据绑定中的Lambda表达式

可以使用lambda表达式来转换数据源或绑定到数据上下文。假设有一个列表,想要显示其所有的名字,可以使用CollectionView和ItemTemplate配合lambda来进行转换。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/presentation"
        xmls:x="http://schemas.microsoft.com/windfx/2006/xaml"
        Title="Lambda Data Biniding"
        Height="350"
        Width="525">
    <Grid>
        <ListBox Name="myLitBox"/>
    </Grid>
</Window>
using Systme.Collections.Generic;
using System.Linq;
using System.Windows;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        InitializeComponent();
        
        List<string> names = new List<string> {"Alice", "Bob", "Charlie"};
        
        // 通过Select方法用lambda表达式给每个名字添加一个前缀,然后将处理后的数据绑定到ListBox控件
        myListBox.ItemsSource = names.Select(name => "Name: " + name);
    }
}

命令绑定中的Lambda表达式

WPF中的命令模式是通过ICommand接口来实现的。可以使用lambda表达式来简化命令的实现。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfs/2006/xaml"
        Title="Lambda Command Demo"
        Height="350"
        Width="525">
    <Grid>
        <Button Content="Execute Command" Command="{Binding ExecuteCommand}"/>
    </Grid>
</Window>
using System.Windows;
using Systme.Windows.Input;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public ICommand ExecuteCommand{get; set;}
        
        public MainWindow()
        {
            InitializeComponent();
            
            ExecuteCommand = new RelayCommand(param => MessageBox.Show("Command Executed"));
            
            DataContext = this;
        }
        
        
        public class RelayCommand : ICommand
        {
            private readonly ACtion<object> _execute;
            
            public RelayCommand(Action<object> execute)
            {
                _execute = execute;
            }
            
            public event EventHandler CanexecuteChanged;
            
            public bool CanExecute(object parameter) => true;
            
            public void Execute(object parameter)
            {
                _execute(paramter);
            }            
        }
    }
}