Подтвердить что ты не робот

Компилятор С# жалуется, что абстрактный класс не реализует интерфейс?

У меня хороший интерфейс, и я хочу реализовать один его член в базовом классе, чтобы клиенты могли получить базовый класс и иметь меньше котельной для записи. Однако, хотя объявленный абстрактный, компилятор жалуется, что класс не реализует интерфейс?!? Как это должно быть сделано?

Код в вопросе:

public interface ITaskDefinition
{
    ITask CreateTask(TaskId id);
    string Name { get; }
    bool HasName { get; }
}

public abstract class TaskDefinitionBase : ITaskDefinition
{
    private string name_ = null;

    public void SetName(string name)
    {
        name_ = name;
    }

    public string Name
    {
        get
        {
            return name_;
        }
    }

    public bool HasName
    {
        get
        {
            return name_ != null;
        }
    }
}

и я получаю следующее сообщение:

ITaskDefinition.cs(15,27): error CS0535: 'NetWork.Task.TaskDefinitionBase' does not implement interface member 'NetWork.Task.ITaskDefinition.CreateTask(NetWork.Task.TaskId)'
4b9b3361

Ответ 1

Вы должны добавить абстрактный шаблон метода:

public abstract ITask CreateTask(TaskId id);

Inheritors могут затем переопределить его для реализации интерфейса.

Ответ 2

Когда объект реализует интерфейс, он должен подчиняться всем ограничениям, применяемым интерфейсом. Это означает, что вы должны реализовать все свойства и методы, объявленные в интерфейсе.

В вашем случае вам не хватает реализации CreateTask. Кроме того, вы должны отметить, что С# использует свойства, в отличие от Java, например, которые используют getters/setters. По этой причине вам не нужен метод SetName.

Код должен выглядеть примерно так:

public abstract class TaskDefinitionBase : ITaskDefinition
{
    private string name_ = null;

    public abstract ITask CreateTask(TaskId id);

    public string Name
    {
        get
        {
            return name_;
        }
        set
        {
            name_ = value
        }
    }

    public bool HasName
    {
        get
        {
            return name_ != null;
        }
    }
}

Ответ 3

TaskDefinitionBase должен включать CreateTask - если вы не хотите его реализовывать, просто отметьте метод как абстрактный, чтобы заставить все классы реализации реализовать его.