tags:

views:

192

answers:

3

I have a nice interface, and I want to implement one member of it in a base class so the clients can derive from the base class and have less boiler-plate to write. However, even though declared abstract, the compiler complains that the class does not implement the interface?!? How is this supposed to be done?

Code in question:

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;
        }
    }
}

and the error I get is:

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

You must add an abstract stub of the method:

public abstract ITask CreateTask(TaskId id);

Inheritors can then override it to implement the interface.

Martinho Fernandes
That's it, I have to explicitly use override in the implementation :/ Thanks!
Anteru
A: 

TaskDefinitionBase needs to include CreateTask - if you don't want to implement it, just mark the method as abstract to force any implementing classes to implement it.

JonoW
+1  A: 

When an object implements an interface it must obey all the constraints applied by the interface. This means that you must implement all properties and methods declared in the interface.

In your case you're missing the implementation of CreateTask. Also, you should note that C# use properties as opposed to Java for example that uses getters/setters. For this reason you don't need a SetName method.

You code should look something like this:

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;
        }
    }
}
Qua
+1 for suggesting making `SetName` a real setter.
Martinho Fernandes