[英]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.