中的计算表达式提供一种用于编写计算的便捷语法,可以通过使用控制流构造和绑定对这些计算进行排序和组合。 根据计算表达式的类型,可以将其视为表示 monad、monoids、monad 转换器和 applicative functor 的一种方式。 但是,与其他语言(例如 Haskell 中的 do-notation)不同,它们不依赖于单一抽象,也不依赖宏或其他形式的元编程来实现上下文相关的便捷语法。
一下是C# 中的一个简单示例,用于计算简单表达式:
#region Demo
public interface ISampleExpression
{
double? Calculate(Dictionary<string, double> parameters);
}
public class ConstantExpression : ISampleExpression
{
double _value;
public ConstantExpression(double value)
{
_value = value;
}
public double? Calculate(Dictionary<string, double> parameters)
{
return _value;
}
}
public class VarExpression : ISampleExpression
{
string _name;
public VarExpression(string name)
{
_name = name;
}
public double? Calculate(Dictionary<string, double> parameters)
{
if (parameters == null
|| !parameters.Any()
|| !parameters.ContainsKey(_name))
{
return default;
}
return parameters[_name];
}
}
public class OperateExpression : ISampleExpression
{
ISampleExpression _leftExp;
ISampleExpression _rightExp;
char _operateSymbol;
public OperateExpression(ISampleExpression leftExp, char operateSymbol, ISampleExpression rightExp)
{
_leftExp = leftExp;
_operateSymbol = operateSymbol;
_rightExp = rightExp;
}
public double? Calculate(Dictionary<string, double> parameters)
{
var leftVal = _leftExp.Calculate(parameters);
var rightVal = _rightExp.Calculate(parameters);
switch (_operateSymbol)
{
case '+':
return leftVal + rightVal;
case '-':
return leftVal - rightVal;
case '*':
return leftVal * rightVal;
case '/':
if (rightVal == 0)
{
return default;
}
return leftVal / rightVal;
default:
break;
}
return default;
}
}
#endregion
上面用于计算表达式的类型
以下程序使用 Expression 类根据不同的 x 和 y 值计算表达式 x * (y + 2) 。
static void Main(string[] args)
{
ISampleExpression e = new OperateExpression(new VarExpression("x"),
'*',
new OperateExpression(
new VarExpression("y"),
'+',
new ConstantExpression(2)
)
);
var vars = new Dictionary<string, double>();
vars["x"] = 3;
vars["y"] = 5;
Console.WriteLine(e.Calculate(vars)); // "21"
vars["x"] = 1.5;
vars["y"] = 9;
Console.WriteLine(e.Calculate(vars)); // "16.5"
}