Alireza Noori
Alireza Noori

Reputation: 15275

The "does not implement interface member" error when using inheritance

I have these 2 interfaces:

public interface IFilterHelper<T>
{
    void Filter(ISearchModel<T> model, ref IQueryable<T> dbModel);
}

public interface ISearchModel<T>
{
    IQueryable<T> GetDBModel(DbContext db);
}

And these 2 implementations

public class UserSearchModel : ISearchModel<ApplicationUser>
{        
    public IQueryable<ApplicationUser> GetDBModel(DbContext db)
    {
        return db.Users.Where(u => true); //something like this
    }
}

public class UserFilterHelper : IFilterHelper<ApplicationUser>
{
    public void Filter(UserSearchModel model, ref IQueryable<ApplicationUser> dbModel)
    {
    }
}

However I get the error 'UserFilterHelper' does not implement interface member 'IFilterHelper<ApplicationUser>.Filter(ISearchModel<ApplicationUser>, ref IQueryable<ApplicationUser>)'

But when I change UserSearchModel with ISearchModel<ApplicationUser>, it compiles successfully. I know I can cast it and get it to work but why does it give me that error. As you can see the UserSearchModel class implements the interface ISearchModel<ApplicationUser>. What am I missing?

Upvotes: 1

Views: 1350

Answers (2)

Van
Van

Reputation: 610

Your UserFilterHelper has the wrong type of parameter in the filter method:

    public class UserFilterHelper : IFilterHelper<ApplicationUser> {

public void Filter(ISearchModel<ApplicationUser> /* Not UserSearchModel */ model, ref IQueryable<ApplicationUser> dbModel)
{
}

}

You will still pass the 'UserSearchModel' in as the parameter. It is only the method signature that requires it to be ISearchModel

Upvotes: 0

Enigmativity
Enigmativity

Reputation: 117175

The interface explicitly requires ISearchModel<ApplicationUser> and even though UserSearchModel implements ISearchModel<ApplicationUser> it isn't the only one that could. I could create a class SuperUserSearchModel that also would implement the same interface.

So trying to write public void Filter(UserSearchModel model, ref IQueryable<ApplicationUser> dbModel) means you are restricting the implementation of the interface.

To make it work you would have to design your interface like this:

public interface IFilterHelper<T, R> where R : ISearchModel<T>
{
    void Filter(R model, ref IQueryable<T> dbModel);
}

public class UserFilterHelper : IFilterHelper<ApplicationUser, UserSearchModel>
{
    public void Filter(UserSearchModel model, ref IQueryable<ApplicationUser> dbModel)
    {
    }
}

Upvotes: 4

Related Questions