David
David

Reputation: 2563

Does not have matching return type error when using interfaces and generics

Why am I getting this error and how can I work around it when I CAN'T change the interfaces... (You can copy/paste the code into an empty CS file)

namespace ClassLibrary1
{
    public interface IEntity
    {
    }

    public interface IEntitySet<T>
    {
    }

    public class Entity : IEntity
    {
    }

    public class EntitySet<T> : IEntitySet<T>
    {
    }

    public interface IImplementer
    {
        IEntitySet<IEntity> Set { get; set; }
    }

    public class Implementer : IImplementer
    {
        // Error 'ClassLibrary1.Implementer' does not implement interface member 'ClassLibrary1.IImplementer.Set'. 
        // 'ClassLibrary1.Implementer.Set' cannot implement 'ClassLibrary1.IImplementer.Set' 
        // because it does not have the matching return type of 'ClassLibrary1.IEntitySet<ClassLibrary1.IEntity>'.
        public EntitySet<Entity> Set { get; set; }
    }
}

Upvotes: 0

Views: 1751

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500595

Indeed, your Set method is meant to have a return type of IEntitySet<IEntity>, but you've tried to declare the implementation using EntitySet<Entity>. Two problems there:

  • IEntitySet isn't EntitySet
  • IEntity isn't Entity

The implementation signature has to match the interface exactly.

You should probably make IImplementer generic, like this:

public interface IImplementer<T> where T : IEntity
{
    IEntitySet<T> Set { get; set; }
}

At that point, you can have:

public class Implementer : IImplementer<Entity>
{
    public IEntitySet<Entity> Set { get; set; }
}

You can then write:

var implementer = new Implementer();
implementer.Set = new EntitySet<Entity>();

Is that what you want? If you really need to force Implementer to use EntitySet rather than just any IEntitySet, then you're probably coupling the two ideas too tightly.

Upvotes: 3

Dan
Dan

Reputation: 10538

You are getting this exception because IImplementer requires an IEntitySet<IEntity> Set property, but your Implementer class is returning an EntitySet<Entity>. EntitySet can be cast to IEntitySet, but IEntitySet cannot be cast to EntitySet, and so the interface implementation fails because you do not satisfy the interface.

Just change public EntitySet<Entity> Set {get; set;} to public IEntitySet<IEntity> Set {get; set;} on your Implementer class.

Upvotes: 1

Related Questions