C# 委托谓词的有用性

C# 委托谓词的有用性,c#,delegates,predicates,C#,Delegates,Predicates,下面的示例使用谓词评估硬编码值为100000的条件。无法向FindPoints方法添加额外的参数,因为它会违反谓词参数约束 这使使用谓词的价值受到质疑。显然,Lambda解决了这个问题。但是,尽管如此,考虑到这个看似奇怪的约束,有人能详细说明谓词在现实生活场景中的有用性吗 如果不接受t以外的参数,为什么还要使用谓词 using System; using System.Drawing; public class Example { public static void Main()

下面的示例使用
谓词
评估硬编码值为100000的条件。无法向
FindPoints
方法添加额外的参数,因为它会违反谓词参数约束

这使使用谓词的价值受到质疑。显然,Lambda解决了这个问题。但是,尽管如此,考虑到这个看似奇怪的约束,有人能详细说明谓词在现实生活场景中的有用性吗

如果不接受t以外的参数,为什么还要使用谓词

using System;
using System.Drawing;

public class Example
{
   public static void Main()
   {
      // Create an array of Point structures.
      Point[] points = { new Point(100, 200), 
                         new Point(150, 250), new Point(250, 375), 
                         new Point(275, 395), new Point(295, 450) };

      // Define the Predicate<T> delegate.
      Predicate<Point> predicate = FindPoints;

      // Find the first Point structure for which X times Y   
      // is greater than 100000. 
      Point first = Array.Find(points, predicate);

      // Display the first structure found.
      Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
   }

   private static bool FindPoints(Point obj)
   {
      return obj.X * obj.Y > 100000;
   }
}
// The example displays the following output: 
//        Found: X = 275, Y = 395
这是我的。
本文给出了很好的示例,但似乎没有解决我的问题。

即使使用lambda表达式声明谓词,提供匿名方法而不是命名方法,lambda仍然只接受特定类型。只是编译器推断出了所需的类型(但请注意,C#实际上允许对lambda语法进行修改,在这里您可以显式指定类型)

因此,这两种方法同样有用;如果您理解其中一个为什么有用(例如lambda语法),那么您就理解了另一个为什么有用

它们都很有用,因为通过传递谓词委托实例,可以自定义正在调用的方法的行为。例如,在本例中,您使用的是
Array.Find()
方法。谓词委托实例的使用,无论是首先存储在局部变量中还是直接传递,无论是使用命名方法还是匿名方法声明,都允许
Array.Find()
方法实现迭代数组的所有枯燥重复工作,同时允许调用方提供感兴趣的,特定于场景的逻辑

要清楚,您的两个示例实际上基本相同,特别是因为您正在处理谓词的静态方法。声明中有一些细微的差别,但一旦优化JIT编译器使用代码完成,运行时执行的实际上是相同的。即使是从C#程序编译的IL在结构上也是一样的,尽管会有一些命名差异。您可以通过比较编译版本来验证这一点,例如使用ildasm.exe工具或类似dotPeek反编译器的工具

我还将指出,您提供了两个示例—使用局部变量和命名方法,以及使用不带局部变量的匿名方法—但至少还有两个其他示例也是类似的:

使用匿名方法的局部变量:

  Predicate<Point> predicate = x => x.X * x.Y > 100000;

  Point first = Array.Find(points, predicate);
  Point first = Array.Find(points, FindPoints);

在最后一个示例中,编译器推断委托类型,自动创建委托实例,就像将方法组名称分配给局部变量时一样。

lambda只是捕获的一种特殊情况(自.NET 2.0以来使用匿名方法可用)反过来,这只是该方法能够访问其自己类的字段的一个特例,自.NET引入以来就可用
  Point first = Array.Find(points, FindPoints);