簡體   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