我正在开发一种由c#表达式树支持的类型脚本语言。我被一个问题困住了,那就是用二进制操作符进行适当的类型转换。这里是我试图模仿的行为的一个例子:(转换规则应该是相同的c#的编译器)
var value = "someString" + 10; // yields a string
var value = 5 + "someString"; // also yields a string, I don't know why
var x = 10f + 10; // yields a float
var y = 10 + 10f; // also yields a float, I don't know why
c#编译器如何知道在第一行的整数上调用ToString(),并在两个方向上将整数转换为浮点数时添加浮点数?这些转换规则是硬编码的吗?
我的编译器现在基本上是这样工作的对于二进制操作符:
Expression Visit(Type tryToConvertTo, ASTNode node) {
// details don't matter. If tryToConvertTo is not null
// the resulting expression is cast to that type if not already of that type
}
// very simplified but this is the gist of it
Expression VisitBinaryOperator(Operator operator) {
Expression lhs = Visit(null, operator.lhs);
Expression rhs = Visit(lhs, operator.rhs); // wrong, but mostly works unless we hit one of the example cases or something similar
switch(operator.opType) {
case OperatorType.Add: {
return Expression.Add(lhs, rhs);
}
// other operators / error handling etc omitted
}
}
我知道总是接受左边的类型是错误的,但是除了硬编码基本类型的规则之外,我不知道解决示例表达式的正确方法是什么。
如果有人能给我指出正确的方向,我将非常感激!这类问题只有通过语言规范才能准确回答。
具有string
和int
操作数的+
算子
https://github.com/dotnet/csharpstandard/blob/draft-v7/standard/expressions.md 1195 -加法操作符
这里,在String concatenation
下,您将看到:
这些二进制
+
操作符的重载执行字符串连接。如果字符串连接的操作数为null
,则替换空字符串。否则,通过调用从object
类型继承的虚拟ToString
方法,将任何非string
操作数转换为其字符串表示形式。如果ToString
返回null
,则替换为空字符串。
具有float
和int
操作数的+
运算符
这里的int
隐式地转换为float
,在这里指定:
https://github.com/dotnet/csharpstandard/blob/draft-v7/standard/conversions.md # 1023 -隐式数值转换