繁体   English   中英

将谓词作为参数传递 c#

[英]Passing a predicate as a parameter c#

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

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();
    }
}

我的问题是 Egg 函数期望什么,为什么?

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

public Egg(Func<IBird> createBird)不是一个函数,它是Egg类的构造函数 由于Egg类必须Hatch鸟类,因此它需要创建鸟类。 Func<IBird>是一个委托,即表示对方法的引用的值。 在这种特定情况下,它代表一个工厂方法 谓词是返回布尔值的方法或委托。 通过此参数,您可以传递任何创建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 "()".
    }
}

现在, Hatch方法可以通过_createBird委托的中间体创建鸟类,而无需知道如何创建或创建哪种类型的鸟。

你会如何创造一个鸡蛋? 好吧,首先你需要一些鸟类实现,例如:

public class BlackBird : IBird
{
    ... your implementation goes here
}

然后你需要一个创建和返回IBird 例如:

IBird CreateBlackBird()
{
    return new BlackBird();
}

然后你可以创建一个鸡蛋

var egg = new Egg(CreateBlackBird); // No "()". CreateBlackBird is not called but referenced.
IBird newBird = egg.Hatch();

确保传递的方法不带参数列表,即不带括号,因为此时你不想调用CreateBlackBird方法,你想把它传递给构造函数,在那里它存储在私有字段_createBird中以后用。

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

var egg = new Egg(() => new BlackBird());

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

在使用颜色作为构造函数参数实现了一个额外的鸟类之后,您可以编写

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

也可以看看:

感谢这个例子。 您可以通过修改 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;
    }
}

您可以通过如下修改 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();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM