Ale*_*kiy 5 .net c# pattern-matching c#-7.0
我编写简单的数学标记器并尝试使用新的C#pattern matching功能.
Tokenizer非常简单:
public IEnumerable<IToken> Tokenize(string input)
{
const char decimalSeparator = '.';
string inputWithoutSpaces = input.Replace(" ", string.Empty);
var numberBuffer = new StringBuilder();
var letterBuffer = new StringBuilder();
foreach (char c in inputWithoutSpaces)
{
switch (c)
{
case var _ when IsTerm(c, letterBuffer):
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
yield return new Operator('*');
}
letterBuffer.Append(c);
break;
case decimalSeparator:
case var _ when IsDigit(c):
numberBuffer.Append(c);
break;
case var _ when IsOperator(c):
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
}
if (letterBuffer.Length > 0)
{
yield return EmptyLetterBufferAsTerm(letterBuffer);
}
yield return new Operator(c);
break;
}
}
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
}
if (letterBuffer.Length > 0)
{
yield return EmptyLetterBufferAsTerm(letterBuffer);
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用case var _因为我想在没有使用if-else if链条的情况下按条件进行匹配,但是如果case when没有指定我就无法写入var variableName.
是否有任何奇特的方式来执行此类操作?或者建议这样做的方法?
有一种“奇特”的方法可以使用通常所说的活动模式来进行这样的模式匹配。虽然 C# 还不支持活动模式,但请参阅此答案,了解它们在实施时可能是什么样子的示例。
因此,使用活动模式,您的代码最终会看起来像这样:
switch (c)
{
case Term(letterBuffer):
...
break;
case decimalSeparator:
case Digit():
...
break;
case Operator():
...
break;
}
Run Code Online (Sandbox Code Playgroud)
如果您希望在 C# 的未来版本中看到此功能,请在 csharplang github 存储库上投票。
与此同时,你的选择是有限的,是坚持if其他人所说的陈述,还是像你一样使用“当守卫”。您选择哪一种实际上只是偏好风格的问题。
| 归档时间: |
|
| 查看次数: |
581 次 |
| 最近记录: |