public Egg(Func<IBird> createBird)
is not a function, it's the constructor of the Egg
class. Since the Egg
class must Hatch
birds, it needs to create birds. Func<IBird>
is a delegate, i.e., a value representing a reference to a method. In this specific case it is representing a factory method. A predicate would be a method or delegate returning a Boolean. Through this parameter you can pass any method creating IBird
s. Since the IBird
interface does not specify an explicit implementation of a bird, you could initialize Egg
with different methods creating different bird types. Some requiring constructor parameters, some not.
You would implement Egg
like this
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 "()".
}
}
Now, the Hatch
method can create birds, without having the knowledge about how or which type of bird to create, through the intermediate of the _createBird
delegate.
How would you create an egg? Well, first you need some bird implementation e.g.:
public class BlackBird : IBird
{
... your implementation goes here
}
Then you need a method creating and returning a IBird
. E.g.:
IBird CreateBlackBird()
{
return new BlackBird();
}
You can then create an egg with
var egg = new Egg(CreateBlackBird); // No "()". CreateBlackBird is not called but referenced.
IBird newBird = egg.Hatch();
Make sure to pass the method without parameter list, i.e. without parentheses, because you don't want to call the CreateBlackBird
method at this point, you want to pass it over to the constructor, where it is stored in the private field _createBird
to be used later.
A lambda expression creates an anonymous delegate on the fly:
var egg = new Egg(() => new BlackBird());
() => new BlackBird()
is a lambda expression. It is equivalent to the CreateBlackBird
method. The return type is not specified and is inferred from the parameter type of the Egg
constructor. It has no name. Only the parameter braces are remaining from the method header. =>
replaces the return
keyword.
After having implemented an additional bird class with a color as constructor parameter, you can write
var egg = new Egg(() => new ColoredBird(Color.Blue));
See also: