c# - 用脚本语言实现简洁的 IF 条件
问题描述
我有一个生成脚本的小助手类,稍后在我的代码中使用,即:
public class ScriptBuilder
{
public string Script { get; set; }
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
Script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
Script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
Script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder setLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
// + other set functions with different parameters/numbers of parameters
}
// ScriptBuilder is used like this :
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = {scriptType}")
.WriteLine($"/! NAME = {name}")
.WriteLine($"/! DESCRIPTION = {description}")
.WriteLine($"/!HEADEND")
/* the header is done now */
.NewLine(2);
这是非常基本的方法链接。我想用这种脚本语言来实现IF
和IF ELSE IF ELSE
,但我没有看到一种非常简洁的方法。
对于IF
我想出了成员函数:
public ScriptBuilder IF(bool condition, ScriptBuilder res)
{
if (condition)
{
return res;
}
else
{
return this;
}
}
可以用作:
ScriptBuilder.IF(condition,
scriptStringBuilder
.setThis(...)
.setThat(...)
;
)
但我不满意,因为
scriptStringBuilder.setThis(...).setThat(...);
已经生效了- 我必须写
scriptStringBuilder
才能使用它。IF ELSE IF ELSE
虽然没有相关的想法。
也许我可以使用代表,例如:
public delegate ScriptBuilder ScriptBuilderFunction(params object[] Parameters);
public ScriptBuilder IF(bool condition, ScriptBuilderFunction func)
{
// ...
}
但我什至不知道如何实现...
理想情况下,我想写:
scriptStringBuilder.
.setThis(...)
.setThat(...)
.IF(condition)
.THEN()
.setThis(...)
.doThat(...)
.ELSEIF(othercondition)
.makeThis(...)
.doThat(...)
.ENDIF()
.setThatNow(...)
;
解决方案
这是您如何实现此功能的非常粗略的草图:
class Program
{
static void Main(string[] args)
{
var number = 999;
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
var text = scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = abc")
.WriteLine($"/! NAME = name")
.WriteLine($"/!HEADEND")
.NewLine(2)
.IfCondition(number != 999, ifCondition => {
ifCondition.NewLine(1);
ifCondition.WriteLine("SUCCESS");
}, elseCondition => {
elseCondition.NewLine(1);
elseCondition.WriteLine("FAIL");
},
elseIf1 => elseIf1.ElseIfCondition(number > 1, h1 => h1.WriteLine("NUMBER IS BIGGER THAN 1")),
elseIf2 => elseIf2.ElseIfCondition(number > 2, h2 => h2.WriteLine("NUMBER IS BIGGER THAN 2")))
.Build();
Console.WriteLine(text);
Console.ReadKey();
}
}
public class ScriptBuilder : IElseIfConditionable
{
private string _script;
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
_script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
_script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
_script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder SetLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
public string Build()
{
return _script;
}
public ScriptBuilder IfCondition(bool condition, Action<ScriptBuilder> trueCondition, Action<ScriptBuilder> falseCondition, params Func<IElseIfConditionable, Tuple<ScriptBuilder, bool>>[] elseIfs)
{
if (condition)
{
trueCondition(this);
return this;
}
foreach (var elseIf in elseIfs)
{
if (elseIf(this).Item2)
{
return this;
}
}
if (!condition)
{
falseCondition(this);
}
return this;
}
public Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition)
{
if (condition)
{
trueCondition(this);
}
return Tuple.Create(this, condition);
}
}
public interface IElseIfConditionable
{
Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition);
}
这相当于:
var s = new ScriptBuilder();
if (number != 999)
{
s.NewLine(1);
s.WriteLine("SUCCESS");
}
else if (number > 1)
{
s.WriteLine("NUMBER IS BIGGER THAN 1");
}
else if (number > 2)
{
s.WriteLine("NUMBER IS BIGGER THAN 2");
}
else
{
s.NewLine(1);
s.WriteLine("FAIL");
}
推荐阅读
- javascript - 尝试使用谷歌地图,但遇到问题
- r - R 函数停止运行,没有可见的错误
- html - 如何使复选框(激活时)更改背景 div 的颜色?
- django - 将 slug 传递到 ListView URL
- firebase - Firebase sendSignInLinkToEmail 需要很长时间才能向用户发送电子邮件
- flutter - 您可以将 AppBar(或类似的东西)添加到 SingleChildScrollView 吗?
- python - Pandas DataFrame ValueError:无法将字符串转换为浮点数:
- r - 计算满足特定条件的行的平均值
- python - TensorFlow 等效于 PyTorch NLLLoss
- javascript - 在 Reactjs 中播放/暂停视频 onScroll