public interface IBird<TBird>
where TBird : IBird<TBird>
public interface IEgg<TBird>
where TBird : IBird<TBird>
public class Chicken : IBird<Chicken>
public IEgg<Chicken> Lay()
return new Egg<Chicken>(() => new Chicken());
public class Duck : IBird<Duck>
return new Egg<Duck>(() => new Duck());
public class Egg<TBird> : IEgg<TBird>
where TBird : IBird<TBird>
private Func<TBird> createBird;
public Egg(Func<TBird> createBird)
this.createBird = createBird;
if (hatched) throw new System.InvalidOperationException("Egg was already hatched");
public static void Main(string[] args)
var chicken1 = new Chicken();
var egg = chicken1.Lay();
var childChicken = egg.Hatch();