Я работаю над типизированным языком сценариев, поддерживаемым деревьями выражений С#. Я застрял в одной проблеме, связанной с правильным преобразованием типов с помощью бинарных операторов. Вот пример поведения, которое я пытаюсь имитировать: (Правила преобразования должны быть одним и тем же компилятором С#)
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
операндамиЗдесь под String concatenation
вы увидите:
Эти перегрузки бинарного оператора
+
выполняют конкатенацию строк. Если операндом конкатенации строк являетсяnull
, то подставляется пустая строка. В противном случае любой операнд, отличный отstring
, преобразуется в строковое представление путем вызова виртуальногоToString
метода, унаследованного от типаobject
. ЕслиToString
возвращаетnull
, подставляется пустая строка.
+
оператор с float
и int
операндамиint
здесь неявно преобразуется в float
, указанное здесь: