Проблема с обобщениями при попытке перенести реализацию языка LOX из книги переводчика крафта на C#

Недавно я обнаружил языковую ошибку, и как часть моего учебного процесса я начал пробираться по книге Боба Нистрома "Переводчики крафта" и пытался воссоздать интерпретатор языка JLOX в C#.

"J" в JLOX относится к образцу кода в Книге, реализуемому на Java.

В разделах "Работа с деревьями" и "Довольно (не очень) симпатичный принтер" Боба представляет шаблон "Посетитель" как решение "Проблемы с выражением".

Я попытался перевести Java-код на C#, но теперь я озадачен следующей ошибкой компилятора:

"ASTPrinter.VisitBinaryExpr(Expression.Binary): не найден подходящий метод для переопределения" (нажмите, чтобы увидеть изображение)

Два соответствующих кодовых файла:

Expression.cs:

используя Систему;

namespace CSharpLox
{
    abstract public class Expression
    {
        abstract public T Accept<T>(Visitor<T> visitor);

        public interface Visitor<T>
        {
            T VisitBinaryExpr(Binary expr);
            // other expression type visitors removed for clarity...
        }

        public class Binary : Expression
        {
            public readonly Expression left;
            public readonly Token _operator;
            public readonly Expression right;

            public Binary(Expression left, Token _operator, Expression right)
            {
                this.left = left;
                this._operator = _operator;
                this.right = right;
            }

            override public T Accept<T>(Visitor<T> visitor)
            {
                return visitor.VisitBinaryExpr(this);
            }
        }

        // other expression types removed for clarity...
    }
}

И ASTPrinter.cs:

using System;
using System.Text;

namespace CSharpLox
{
    // ASTPrinter.cs
    public class ASTPrinter : Expression.Visitor<string>
    {
        override public string VisitBinaryExpr(Expression.Binary expression)
        {
            return parenthesize(expression._operator.lexeme, expression.left, expression.right);
        }

        private String parenthesize(String name, params Expression[] expressions)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("(").Append(name);

            foreach (Expression expression in expressions)
            {
                builder.Append(" ");
                builder.Append(expression.Accept(this));
            }

            builder.Append(")");

            return builder.ToString();
        }
    }
}

Ошибка, которую я не знаю, как решить, находится в этой строке ASTPrinter.cs:

переопределить открытую строку VisitBinaryExpr(выражение Expression.Binary)

Текст ошибки, сообщаемый редактором Visual Studio:

Ошибка CS0115 "ASTPrinter.VisitBinaryExpr(Expression.Binary)": не найден подходящий метод для переопределения

Я думаю, я просто не знаю достаточно о типах возвращаемых C#.

Я копался в поисках информации об общих типах возвращаемых данных, но до сих пор я не нашел четкого примера того, как он будет взаимодействовать с конкретной реализацией абстрактного интерфейса. Или, возможно, это область, в которой возможности Generics в C# и Java слишком сильно различаются для прямого перевода реализации.

Любой совет будет принят во внимание.

1 ответ

Решение

Ваш Expression.Visitor<string> это интерфейс, так что нечего переопределять.

Проще говоря:

public string VisitBinaryExpr(Expression.Binary expression)

Вам нужно только override когда базовый класс уже определил метод с той же сигнатурой, которая была объявлена ​​как vitrual или же abstract,

В вашем случае класс ASTPrinter вытекает непосредственно из System.Object,

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