Как компилятор 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
    }
}

Я знаю, что всегда принимать тип левой стороны неправильно, но я понятия не имею, каким может быть правильный подход к разрешению примеров выражений, кроме жесткого кодирования правил для примитивных типов.

Если кто-то может указать мне в правильном направлении, я был бы очень благодарен!

stackoverflow.com/a/3398629/425871
Steve 03.12.2022 23:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На такие вопросы можно точно ответить только с помощью спецификации языка.

+ оператор с string и int операндами

https://github.com/dotnet/csharpstandard/blob/draft-v7/standard/expressions.md#1195-дополнение-оператор

Здесь под String concatenation вы увидите:

Эти перегрузки бинарного оператора + выполняют конкатенацию строк. Если операндом конкатенации строк является null, то подставляется пустая строка. В противном случае любой операнд, отличный от string, преобразуется в строковое представление путем вызова виртуального ToString метода, унаследованного от типа object. Если ToString возвращает null, подставляется пустая строка.

+ оператор с float и int операндами

int здесь неявно преобразуется в float, указанное здесь:

https://github.com/dotnet/csharpstandard/blob/draft-v7/standard/conversions.md#1023-implicit-numeric-conversions

Другие вопросы по теме