编辑
2025-02-10
C# 应用
00
请注意,本文编写于 85 天前,最后修改于 85 天前,其中某些信息可能已经过时。

目录

1. Func<T, TResult>
示例1:基本用法
示例2:作为方法参数
2. Predicate<T>
示例3:使用Predicate
示例4:Predicate vs Func
3. Expression<T>
示例5:基本Expression
示例6:构建动态查询
总结

在C# .NET中,Func、Predicate和Expression是三种常用的委托和表达式类型,它们在编写灵活、可重用的代码时非常有用。本文将详细介绍这三种类型,并提供多个实例来说明它们的用法和区别。

1. Func<T, TResult>

Func是一个通用委托,它可以接受零个或多个输入参数,并返回一个值。其基本形式为:

C#
public delegate TResult Func<out TResult>(); public delegate TResult Func<in T, out TResult>(T arg); public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2); // ... 最多可以有16个输入参数

示例1:基本用法

C#
Func<int, int, string> formatNumber = (a, b) => $"The sum of {a} and {b} is {a + b}"; string result = formatNumber(5, 3); Console.WriteLine(result);

image.png

示例2:作为方法参数

C#
public static List<int> FilterList(List<int> numbers, Func<int, bool> filterFunc) { return numbers.Where(filterFunc).ToList(); } static void Main(string[] args) { // 使用 List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; List<int> evenNumbers = FilterList(numbers, n => n % 2 == 0); Console.WriteLine(string.Join(", ", evenNumbers)); }

image.png

2. Predicate

Predicate是一个特殊的Func,它始终返回一个布尔值。它通常用于定义过滤条件。

C#
public delegate bool Predicate<in T>(T obj);

示例3:使用Predicate

C#
static void Main(string[] args) { List<string> fruits = new List<string> { "apple", "banana", "cherry", "date", "elderberry" }; Predicate<string> startsWithB = s => s.StartsWith("b", StringComparison.OrdinalIgnoreCase); string bFruit = fruits.Find(startsWithB); Console.WriteLine(bFruit); }

image.png

示例4:Predicate vs Func

C#
static void Main(string[] args) { // 使用Predicate Predicate<int> isEven = n => n % 2 == 0; List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; List<int> evenNumbers = numbers.FindAll(isEven); // 使用Func Func<int, bool> isOdd = n => n % 2 != 0; List<int> oddNumbers = numbers.Where(isOdd).ToList(); Console.WriteLine($"Even numbers: {string.Join(", ", evenNumbers)}"); Console.WriteLine($"Odd numbers: {string.Join(", ", oddNumbers)}"); }

image.png

3. Expression

Expression表示一个可以编译和执行的代码块。它们通常用于构建动态查询、规则引擎或者在运行时修改代码行为。

示例5:基本Expression

C#
static void Main(string[] args) { Expression<Func<int, bool>> isPositive = n => n > 0; // 编译并执行Expression Func<int, bool> compiledFunc = isPositive.Compile(); bool result = compiledFunc(5); Console.WriteLine(result); }

image.png

示例6:构建动态查询

C#
public class Person { public string Name { get; set; } public int Age { get; set; } } public static Expression<Func<Person, bool>> BuildAgeRangeExpression(int minAge, int maxAge) { ParameterExpression parameter = Expression.Parameter(typeof(Person), "p"); Expression left = Expression.Property(parameter, "Age"); Expression minAgeCheck = Expression.GreaterThanOrEqual(left, Expression.Constant(minAge)); Expression maxAgeCheck = Expression.LessThanOrEqual(left, Expression.Constant(maxAge)); Expression combinedCheck = Expression.AndAlso(minAgeCheck, maxAgeCheck); return Expression.Lambda<Func<Person, bool>>(combinedCheck, parameter); } static void Main(string[] args) { // 使用 List<Person> people = new List<Person> { new Person { Name = "Alice", Age = 25 }, new Person { Name = "Bob", Age = 30 }, new Person { Name = "Charlie", Age = 35 }, new Person { Name = "David", Age = 40 } }; var ageRangeExpression = BuildAgeRangeExpression(28, 38); var filteredPeople = people.AsQueryable().Where(ageRangeExpression); foreach (var person in filteredPeople) { Console.WriteLine($"{person.Name} - {person.Age}"); } }

image.png

总结

  1. Func<T, TResult> 是一个通用委托,可以接受多个输入参数并返回一个值。它非常灵活,适用于多种场景。
  2. Predicate 是Func的一个特例,专门用于返回布尔值的情况。它通常用于定义过滤条件。
  3. Expression 表示可编译和执行的代码块。它允许在运行时检查、修改和编译代码,特别适用于构建动态查询和规则引擎。

这三种类型在C# .NET编程中扮演着重要角色,能够帮助开发者编写更加灵活、可重用和高效的代码。根据具体的使用场景,选择合适的类型可以大大提高代码的表现力和可维护性。

本文作者:rick

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!