跳转到内容

C Sharp Predicate 委托

来自代码酷

C# Predicate委托[编辑 | 编辑源代码]

Predicate委托是C#中预定义的泛型委托类型,用于表示对一个特定条件进行测试的方法。它通常用于集合操作中,根据指定的条件筛选元素。Predicate委托返回一个布尔值,指示输入对象是否满足条件。

定义与语法[编辑 | 编辑源代码]

Predicate委托的声明如下:

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

其中:

  • T:输入参数的类型
  • obj:要测试的对象
  • 返回值:如果obj满足条件则返回true,否则返回false

基本用法[编辑 | 编辑源代码]

以下示例展示如何声明和使用Predicate委托:

// 定义一个检查数字是否为偶数的Predicate
Predicate<int> isEven = num => num % 2 == 0;

// 使用Predicate
Console.WriteLine(isEven(4));  // 输出: True
Console.WriteLine(isEven(5));  // 输出: False

与集合操作结合[编辑 | 编辑源代码]

Predicate委托常用于List<T>的FindAll、Find、Exists等方法中:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// 使用Predicate查找所有偶数
List<int> evenNumbers = numbers.FindAll(isEven);

Console.WriteLine(string.Join(", ", evenNumbers));  // 输出: 2, 4, 6

Lambda表达式简化[编辑 | 编辑源代码]

可以直接使用Lambda表达式替代显式Predicate声明:

List<string> names = new List<string> { "Alice", "Bob", "Charlie", "David" };

// 使用Lambda表达式作为Predicate
var longNames = names.FindAll(name => name.Length > 4);

Console.WriteLine(string.Join(", ", longNames));  // 输出: Alice, Charlie, David

实际应用场景[编辑 | 编辑源代码]

场景1:数据筛选[编辑 | 编辑源代码]

在数据处理中,Predicate可用于筛选符合特定条件的数据:

class Product {
    public string Name { get; set; }
    public decimal Price { get; set; }
}

List<Product> products = new List<Product> {
    new Product { Name = "Laptop", Price = 999.99m },
    new Product { Name = "Mouse", Price = 25.50m },
    new Product { Name = "Keyboard", Price = 49.99m }
};

// 筛选价格低于50的产品
Predicate<Product> isCheap = p => p.Price < 50;
var cheapProducts = products.FindAll(isCheap);

foreach (var product in cheapProducts) {
    Console.WriteLine($"{product.Name}: {product.Price}");
}
// 输出:
// Mouse: 25.50
// Keyboard: 49.99

场景2:验证规则[编辑 | 编辑源代码]

Predicate可用于实现验证逻辑:

Predicate<string> isValidEmail = email => 
    email.Contains("@") && email.EndsWith(".com");

Console.WriteLine(isValidEmail("test@example.com"));  // True
Console.WriteLine(isValidEmail("invalid.email"));    // False

Predicate与其他委托的比较[编辑 | 编辑源代码]

classDiagram class Predicate{ +bool Invoke(T obj) } class Func{ +TResult Invoke(T arg) } class Action{ +void Invoke(T arg) } Predicate --|> Delegate Func --|> Delegate Action --|> Delegate

主要区别:

  • Predicate<T>:接受一个参数并返回bool
  • Func<T, bool>:功能上与Predicate相同,但属于Func委托家族
  • Action<T>:接受一个参数但不返回值

性能考虑[编辑 | 编辑源代码]

使用Predicate委托会有微小的性能开销,因为涉及委托调用。在性能关键的代码中,可以考虑直接使用方法调用或内联代码。

数学表示[编辑 | 编辑源代码]

Predicate可以表示为从类型T到布尔值的函数: P:T{true,false}

总结[编辑 | 编辑源代码]

  • Predicate委托是返回bool值的单参数委托
  • 主要用于集合筛选和条件测试
  • 可以使用Lambda表达式简化语法
  • 功能上等同于Func<T, bool>,但语义更明确
  • 在LINQ中,通常使用Func<T, bool>替代Predicate

进阶练习[编辑 | 编辑源代码]

1. 创建一个Predicate<int>,检查数字是否为质数 2. 使用Predicate<string>实现一个密码强度验证器 3. 比较List<T>.FindAll(Predicate)与LINQ Where()方法的性能差异