C# 将谓词作为参数c传递#

C# 将谓词作为参数c传递#,c#,predicate,func,C#,Predicate,Func,我最近做了一个公司的评估,他们有一个案例,他们想设置一个谓词作为方法的输入参数。我对此几乎没有经验,我一直在自己研究。代码如下所示: using System; public interface IBird { Egg Lay(); } public class Chicken : IBird { public Chicken() { } public void EggLay() { } public Egg Lay()

我最近做了一个公司的评估,他们有一个案例,他们想设置一个谓词作为方法的输入参数。我对此几乎没有经验,我一直在自己研究。代码如下所示:

using System;

public interface IBird
{
    Egg Lay();
}

public class Chicken : IBird
{
    public Chicken()
    {
    }

    public void EggLay()
    {
    }

    public Egg Lay()
    {
        return new Egg();
    }
}

public class Egg
{
    public Egg(Func<IBird> createBird)
    {
        throw new NotImplementedException("Waiting to be implemented.");
    }

    public IBird Hatch()
    {
        throw new NotImplementedException("Waiting to be implemented.");
    }
}

public class Program
{
    public static void Main(string[] args)
    {
//      var chicken1 = new Chicken();
//      var egg = chicken1.Lay();
//      var childChicken = egg.Hatch();
    }
}
使用系统;
公共接口IBird
{
产卵();
}
公营鸡:IBird
{
公鸡()
{
}
公共图书馆
{
}
公共产卵
{
还新蛋();
}
}
公营鸡蛋
{
公共蛋(Func createBird)
{
抛出新的NotImplementedException(“等待实现”);
}
公共IBird舱口()
{
抛出新的NotImplementedException(“等待实现”);
}
}
公共课程
{
公共静态void Main(字符串[]args)
{
//var chicken1=新鸡();
//var egg=chicken1.Lay();
//var childChicken=egg.Hatch();
}
}
我的问题是什么是鸡蛋的功能预期和为什么

我已经看过了,但仍然没有任何意义。在这一点上它是学术性的,但我真的想理解。

public Egg(Func createBird)
不是一个函数,它是
Egg
类的核心。由于
Egg
类必须
Hatch
birds,因此它需要创建birds
Func
是一个委托,即表示方法引用的值。在这个特定的例子中,它代表一个。谓词将是返回布尔值的方法或委托。通过此参数,您可以传递任何创建IBird的方法。由于
IBird
接口没有指定鸟的显式实现,因此可以使用创建不同鸟类型的不同方法初始化
Egg
。有些需要构造函数参数,有些不需要

您可以像这样实现
Egg

public class Egg
{
    private readonly Func<IBird> _createBird;

    public Egg(Func<IBird> createBird)
    {
        _createBird = createBird; // No "()". createBird is not called, just assigned.
    }

    public IBird Hatch()
    {
        return _createBird(); // Here createBird is called, therefore the "()".
    }
}
然后需要一个方法来创建并返回
IBird
。例如:

IBird CreateBlackBird()
{
    return new BlackBird();
}
然后,您可以创建一个带有

var egg = new Egg(CreateBlackBird); // No "()". CreateBlackBird is not called but referenced.
IBird newBird = egg.Hatch();
确保传递不带参数列表的方法,即不带括号的方法,因为此时不想调用
CreateBlackBird
方法,而是希望将其传递给构造函数,在构造函数中,它存储在私有字段
\u createBird
中,以供以后使用

lambda表达式动态创建匿名委托:

var egg = new Egg(() => new BlackBird());
()=>new BlackBird()
是一个lambda表达式。它相当于
CreateBlackBird
方法。未指定返回类型,它是从
Egg
构造函数的参数类型推断出来的。它没有名字。方法头中只剩下参数大括号
=>
替换
返回
关键字

在实现了一个附加的bird类,并将颜色作为构造函数参数之后,您可以编写

var egg = new Egg(() => new ColoredBird(Color.Blue));
另见:

    • 谢谢您的示例。 您可以实现singleton模式,以便通过修改Egg类使鸟只能孵化一次,如下所示:

          public class Egg
      {
          private readonly Func<IBird> _createBird;
          private IBird _Bird = null;
      
          public Egg(Func<IBird> createBird)
          {
              _createBird = createBird;
          }
      
          public IBird Hatch()
          {
              if (_Bird == null)
              {
                  _Bird = _createBird();
              }
      
              return _Bird;
          }
      }
      
      公共类鸡蛋
      {
      私有只读函数;
      私有IBird_Bird=null;
      公共蛋(Func createBird)
      {
      _createBird=createBird;
      }
      公共IBird舱口()
      {
      如果(_Bird==null)
      {
      _小鸟=_createBird();
      }
      返回鸟;
      }
      }
      
      您可以实现singleton模式,通过如下修改Egg类,鸟类只能孵化一次

      public interface IBird
          {
              Egg Lay();
          }
          public class Egg
          {
              private readonly Func<IBird> _createBird;
              private bool _hatched;
      
              public Egg(Func<IBird> createBird)
              {
                  _createBird = createBird;
              }
      
              public IBird Hatch()
              {
                  if (_hatched)
                      Console.WriteLine("Egg are already hatched");
                  _hatched = true;
                  Console.WriteLine("Egg are hatched now;");
                  Console.ReadKey();
                  return _createBird();
              }
          }
      
          public class Chicken : IBird
          {
              public Egg Lay()
              {
                  var egg = new Egg(() => new Chicken());
                  return egg;
              }
          }
      
          public class Program
          {
              public static void Main(string[] args)
              {
                  var chicken1 = new Chicken();
                  var egg = chicken1.Lay();
                  var childChicken = egg.Hatch();
              }
          }
      
      公共接口IBird
      {
      产卵();
      }
      公营鸡蛋
      {
      私有只读函数;
      二等兵布卢孵化;
      公共蛋(Func createBird)
      {
      _createBird=createBird;
      }
      公共IBird舱口()
      {
      如果(_阴影)
      控制台。WriteLine(“蛋已经孵化”);
      _阴影=真;
      控制台.WriteLine(“蛋现在孵化了;”);
      Console.ReadKey();
      返回_createBird();
      }
      }
      公营鸡:IBird
      {
      公共产卵
      {
      var egg=新鸡蛋(()=>新鸡肉());
      回卵;
      }
      }
      公共课程
      {
      公共静态void Main(字符串[]args)
      {
      var chicken1=新鸡();
      var egg=chicken1.Lay();
      var childChicken=egg.Hatch();
      }
      }
      
      您链接的答案非常好,到底是什么混淆?我应该传递给Egg函数什么?我只是不明白它期待什么,为什么期待它。当使用Main方法中的示例作为值时,egg方法需要什么来正确创建“鸡”蛋?作为旁白,
      Func
      不是谓词。谓词类似于
      Func
      predicate
      。您一般对委托了解多少?现在很难知道如何回答这个问题,因为可以说,我们不知道要返回多远。A本质上是一个函数指针。
      public interface IBird
          {
              Egg Lay();
          }
          public class Egg
          {
              private readonly Func<IBird> _createBird;
              private bool _hatched;
      
              public Egg(Func<IBird> createBird)
              {
                  _createBird = createBird;
              }
      
              public IBird Hatch()
              {
                  if (_hatched)
                      Console.WriteLine("Egg are already hatched");
                  _hatched = true;
                  Console.WriteLine("Egg are hatched now;");
                  Console.ReadKey();
                  return _createBird();
              }
          }
      
          public class Chicken : IBird
          {
              public Egg Lay()
              {
                  var egg = new Egg(() => new Chicken());
                  return egg;
              }
          }
      
          public class Program
          {
              public static void Main(string[] args)
              {
                  var chicken1 = new Chicken();
                  var egg = chicken1.Lay();
                  var childChicken = egg.Hatch();
              }
          }