发现op_addition或实现expression.add的实现方法
-
03-10-2019 - |
题
我正在使用ANTLR和表达树编写语言。
我为生成添加时定义了一种标准的工厂方法,可用于我的树解析器,并且它适用于内置的整体类型,现在我正在转向更多的一般类型。
目前,它是非常幼稚的,它只是这样做的(在进行中TDD代码通常看起来很天真!?):
protected Expression GenerateAdd(Expression left, Expression right)
{
if (left.Type.Equals(right.Type))
return Expression.Add(left, right);
if (left.Type.IsValueType && right.Type.IsValueType)
Promote7_2_6_2(ref left, ref right);
return Expression.Add(left, right);
}
在哪里 Promote7_2_6_2
生成遵循C#Spec 7.2.6.2列出的积分促销规则的转换表达式(该语言将与C#相似,但会与JScript交叉,并具有其他全新的关键字)。
自然,我继续测试字符串添加 - 即 "a" + "b";
我得到错误:
System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.
足够公平 - 我反映了系统。斯特林和确保确实没有定义操作员。在这样的测试方法中生成表达树:
Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;
表明确实创建了添加二进制表达,但是将实现方法设置为 string.Concat
方法。
我知道在某些情况下,我将不得不考虑这样做,但是有多少其他类型可以通过这种方式定义添加?是 string
?
它是嵌入C#编译器中的规则吗?还是可以使用某种可发现的元数据来自动发现其他类型的此类方法?
提前致谢!
解决方案
看来我在回答自己的问题方面做得很好!
我很抱歉,这个答案可以更好地格式化,但是我遵循我的HTC欲望,其键盘并不支持所有符号!
似乎没有办法在运行时“发现”这些规则,主机语言的责任是决定如何实现诸如字符串添加之类的内容。 C#在加法中适应了连续项的数量,调用最适当匹配的.concat方法。
因此,如果我希望我的语言支持不为其定义运算符的集体实例的添加,例如,我可以简单地编写或找到静态方法(当然是正确的签名!)在这种情况下使用它的语言。这里的一个经典示例是是否通过静态数组方法支持Array1 + Array2。
至于发现运算符,ADD.ADD方法会考虑到这一点,但是它不会自动执行任何转换,因此,就像我在问题中引用的积分/浮点促销方法一样,这再次取决于语言的在尝试构建表达式之前,确定是否需要其他转换。
因此,最好首先反映操作员,看看是否为两种类型定义了操作员,然后在考虑转换之前是否存在。