tags:

views:

212

answers:

2

Please note: I am writing this question.

I have these interfaces in a library/framework I am working on:

interface IRepository<TKey,TModel> where TModel: IModel<TKey>{ 
    void Remove(TModel entity);
}

interface IRepository<T> : IRepository<int, T> where T: IModel { }

interface ISoftDeleteRepository<TKey,TModel> : IRepository<TKey, TModel> 
where TModel: IModel<TKey>    
{ }

interface ISoftDeleteRepository<TModel> 
    : ISoftDeleteRepository<int, TModel>, IRepository<TModel> { }

and these implementations

class Repository<TKey,TModel> : IRepository<TKey, TModel>
where TModel: IModel<TKey>
{ 
    void Remove(TModel entity)
    {
    // actually Delete
    }
}

class Repository<T> : Repository<int,T>, IRepository<T>
where T: IModel
 { }

class SoftDeleteRepository<TKey,TModel> : Repository<TKey, TModel> ISoftDeleteRepository<TKey,TModel> 
where TModel: ISoftDeleteModel<TKey> { 
    override void Remove(TModel entity)
    {
    // actually do an update instead
    }
 }

class SoftDeleteRepository<TModel> 
    : SoftDeleteRepository<int, TModel>, ISoftDeleteRepository<TModel>
 where TModel: ISoftDeleteModel { }

I inherit and implement my own ISoftDeleteRespository

interface IEventRepository : ISoftDeleteRepository<Event> { }

class EventRepository : SoftDeleteRepository<Event>, IEventRepository { }

When I call iEventRepository.Remove(...) calls the IRepository's Remove in Repository. I don't want that to happen I want to call ISoftDeleteRepository's Remove.

Has any one run into anything like this? The real code just compiles just fine, most of this was reconstructed from memory.

+1  A: 

Since your interfaces define methods with the same signature, you need to use explicit interface implementation in the first place, or you couldn't even compile your code.

The next problem you may have run into is calling your method. You need to call it on an instance of the correct interface, not on the class type (which shouldn't be possible if both methods are implemented explicitly). Cast first, then call.

EDIT: Just noticed your Repository<> Remove method needs to be marked virutal! You should have got a compiler warning about using new instead of override to shadow Repository.Remove<>() in your derived class. Always treat warnings as error.

Btw, (I really couldn't resist it): Premature generalization is the root of all evil.

Johannes Rudolph
A: 

I've had to alter the code you provided in the question quite a bit to make it pass compilation. Whether it does what you want it to do though, I've no idea.

As just one example, SoftDeleteRepository needs to inherit from a class in order to override any methods, as you've provided it, it only implements an interface.

interface IRepository<TKey, TModel>
{
    void Remove(TModel entity);
}

interface IRepository<T> : IRepository<int, T> { }

interface ISoftDeleteRepository<TKey, TModel> : IRepository<TKey, TModel> { }

interface ISoftDeleteRepository<TModel> : ISoftDeleteRepository<int, TModel>, IRepository<TModel> { }

interface IEventRepository : ISoftDeleteRepository<Event> { }

class Repository<TKey, TModel> : IRepository<TKey, TModel>
{
    public virtual void Remove(TModel entity)
    {
        // actually Delete 
    }
}

class Repository<T> : Repository<int, T>, IRepository<T> { }

class SoftDeleteRepository<TKey, TModel> : Repository<TKey, TModel>, ISoftDeleteRepository<TKey, TModel>
{
    public override void Remove(TModel entity)
    {
        // actually do an update instead 
    }
}

class SoftDeleteRepository<TModel> : SoftDeleteRepository<int, TModel>, ISoftDeleteRepository<TModel> { }

class EventRepository : SoftDeleteRepository<Event>, IEventRepository { }

class Event { }
Daniel Renshaw
Sorry, I was able to fix some of it. Most of the code was from memory.
Daniel A. White