gpt4 book ai didi

c# - 在 C# 中编写我的第一个 DSL 并挂断了 func & Action

转载 作者:太空狗 更新时间:2023-10-29 21:37:09 28 4
gpt4 key购买 nike

我正在努力为工作中的一个简单工具编写我的第一个 DSL。我正在使用构建器模式来设置复杂的父对象,但在构建父对象的子集合时遇到了障碍。这是一个示例:

使用:

var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);

闭包示例(我想这就是它们的名称):

var myMorningCoffee = Coffee.Make.WithCream().PourIn( 
x => {
x.ShotOfExpresso.AtTemperature(100);
x.ShotOfExpresso.AtTemperature(100).OfPremiumType();
}
).WithOuncesToServe(16);

示例类(没有子 PourIn() 方法,因为这是我想要弄清楚的。)

 public class Coffee
{
private bool _cream;

public Coffee Make { get new Coffee(); }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}

所以在我的工作应用程序中,我可以很好地构建复杂的对象,但我终究无法弄清楚如何为父对象的子集合编码 lambda。 (在这个例子中是 expresso 的镜头(子集合))。

也许我在这里混淆了概念,但我不介意直截了当;但是,我真的很喜欢它的阅读方式,并想弄清楚如何让它发挥作用。

谢谢,山姆

最佳答案

好的,所以我想出了如何使用额外的表达式构建器来编写我的 DSL。这就是我希望我的 DSL 阅读的方式:

var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);

这是我通过的测试:

[TestFixture]
public class CoffeeTests
{
[Test]
public void Can_Create_A_Caramel_Macchiato()
{
var myPreferredCoffeeFromStarbucks =
Coffee.Make.WithCream().PourIn(
x =>
{
x.ShotOfExpresso().AtTemperature(100);
x.ShotOfExpresso().AtTemperature(100).OfPremiumType();
}
).ACupSizeInOunces(16);

Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Count == 2);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == true);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.expressoExpressions[0].ExpressoShots.Dequeue().IsOfPremiumType == false);
Assert.IsTrue(myPreferredCoffeeFromStarbucks.CupSizeInOunces.Equals(16));
}
}

这是我的 CoffeeExpressionBuilder DSL 类:

public class Coffee
{
public List<ExpressoExpressionBuilder> expressoExpressions { get; private set; }

public bool HasCream { get; private set; }
public int CupSizeInOunces { get; private set; }

public static Coffee Make
{
get
{
var coffee = new Coffee
{
expressoExpressions = new List<ExpressoExpressionBuilder>()
};

return coffee;
}
}

public Coffee WithCream()
{
HasCream = true;
return this;
}

public Coffee ACupSizeInOunces(int ounces)
{
CupSizeInOunces = ounces;

return this;
}

public Coffee PourIn(Action<ExpressoExpressionBuilder> action)
{
var expression = new ExpressoExpressionBuilder();
action.Invoke(expression);
expressoExpressions.Add(expression);

return this;
}

}

public class ExpressoExpressionBuilder
{
public readonly Queue<ExpressoExpression> ExpressoShots =
new Queue<ExpressoExpression>();

public ExpressoExpressionBuilder ShotOfExpresso()
{
var shot = new ExpressoExpression();
ExpressoShots.Enqueue(shot);

return this;
}

public ExpressoExpressionBuilder AtTemperature(int temp)
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.Temperature = temp;

return this;
}

public ExpressoExpressionBuilder OfPremiumType()
{
var recentlyAddedShot = ExpressoShots.Peek();
recentlyAddedShot.IsOfPremiumType = true;

return this;
}
}

public class ExpressoExpression
{
public int Temperature { get; set; }
public bool IsOfPremiumType { get; set; }

public ExpressoExpression()
{
Temperature = 0;
IsOfPremiumType = false;
}
}

欢迎提出任何建议。

关于c# - 在 C# 中编写我的第一个 DSL 并挂断了 func<T> & Action,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1794848/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com