Я создал собственную систему типов для использования в сценариях C # внутри приложения. Скрипты компилируются на лету и позволяют взаимодействовать с внутренними данными приложения. Эта система типов разработана абстрактно с использованием таких интерфейсов, как IValue
. Реализация IValue
может быть RefString
, RefInteger
, RefDouble
(среди многих других, но этого достаточно для демонстрации моей проблемы).
Теперь мы подошли к моменту, когда я застрял ... Использование этих IValue
объектов несколько неестественно. Рекомендуется всегда использовать интерфейсы для взаимодействия с объектами, но нет возможности определить неявное преобразование или перегрузку оператора для интерфейсов. Это приводит к ситуациям, когда уродливое явное приведение неизбежно, так что используется правильный оператор.
Пример:
IValue Add(IValue a, IValue b)
{
//return a+b; // won't work: which operator +() to use?
return (RefInteger)a + (RefInteger)b;
}
В случае C # в выражениях, включающих типы значений, предоставляются неявные преобразования. Каков хороший способ разработки такой нестандартной системы?
Я переписал систему типов, удалив интерфейс IValue
и введя базовый класс RefValue
. Таким образом, часть явных приведений уже может быть устранена. Я реализовал некоторую перегрузку операторов в этом базовом классе, но это вызвало много проблем с операторами преобразования по умолчанию ... Помимо этого, логика для реализации в реализации оператора подразумевает много знаний о типах в системе. Я думаю, что это все равно путь, по которому нужно идти, но каковы правила, которым нужно следовать, чтобы осуществить это хорошим и безопасным способом?
РЕДАКТИРОВАТЬ : Поработав некоторое время, я смог выяснить некоторые правила:
- Объявление неявных только операторов преобразования из базовых типов (int, double, string, ...)
- Объявите явные преобразования в базовые типы (чтобы избежать неявного приведения к int !! что происходит довольно часто, но почему?)
- Во избежание неоднозначных вызовов операторы +, -, /, * не должны быть переопределены в базовом классе и в производных классах. [Каков путь тогда? Я сделал операцию перегрузки в производных классах, это требует приведения на использование, что опять-таки некрасиво ...]