Открытие метода OP_ADDIation или реализации для Expression.Add

StackOverflow https://stackoverflow.com/questions/3721994

Вопрос

Я пишу язык, используя деревья 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 Генерирует конвертировать выражения, которые следуют правилам для интегрального продвижения, как указано в Spec 7.2.6.2 C # 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'.

Достаточно справедливо - я отражаю систему .String и наверняка, что оператор действительно не определен. Создание дерева выражения в методе теста, подобного этому:

Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;

Показывает, что Add Binaryexpression действительно создается, но с методом реализации, установленным на один из string.Concat методы.

Я знал, что мне придется посмотреть, что делает что-то вроде этого в некоторых случаях, но сколько других типов определяют дополнение таким образом? Это просто string?

Это правило, встроенное в C # Compiler - или есть ли какие-то обнаруженные метаданные данные, которые я могу использовать для автоматического обнаружения таких методов на других типах?

Заранее спасибо!

Это было полезно?

Решение

Кажется, я делаю отличную линию в ответах на мои вопросы!

Мои извинения, этот ответ может быть лучше отформатирован, но я нахожусь в своем HTC Desire, и его клавиатура не поддерживает все символы!

Похоже, что нет никакого способа «обнаружить» эти правила во время выполнения, это ответственность языка хозяина, чтобы решить, как реализовать такие вещи, как сложное. C # адаптируется к количеству последовательных терминов в дополнение, вызывая метод .Concat, который наиболее соответственно соответствует этому.

Итак, если я желаю моему языку поддерживать добавление экземпляров классов, когда оператор не определен для него, например, я могу просто написать или найти статический метод, чтобы сделать это (из правильной подписи курса!), А затем сложно Язык для его использования в этом случае. Классический пример здесь состоит в том, поддерживает ли Array1 + Array2 через статические методы массива.

Что касается обнаружения операторов, метод Expression.Add позаботится об этом, но он не работает автоматически никаких преобразований, поэтому, как с помощью метода продвижения в интеграл / с плавающей точкой, которого я ссылаюсь на вопрос, снова это зависит от языка Правила для определения того, необходимы ли другие преобразования, прежде чем пытаться построить выражение.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top