0

I know there are plenty of questions around generics, inheritance and type inference. But I really struggle to understand some reasoning behind the current behavior. I will point out in the example what I want to achieve by the end.

interface IState { }
interface IEntity<T> where T : IState
{
    T Get();
    void Set(T model);
}

interface IRepository<T>
{
    T GetById(Guid id);
    void Save(T model);
}

class RepositoryA<T, V> 
    : IRepository<T> where T 
    : IEntity<V> where V 
    : IState
{
    public T GetById(Guid id) {}
    public void Save(T model) {}
}
class RepositoryB<T>
    : IRepository<T> where T
    : IEntity<IState>
{
    public T GetById(Guid id) {}
    public void Save(T model) {}
}

class Program
{
    static void Main(string[] args)
    {
        IRepository<FireEntity> repoA = new RepositoryA<FireEntity, FireState>(); // Compiles fine
        IRepository<FireEntity> repoB = new RepositoryB<FireEntity>(); // Compilation Error: FireEntity must be convertible to IEntity<IState>

        IEntity<FireState> a = new FireEntity(); // Compiles fine
        IEntity<IState> b = new FireEntity(); // fails to convert
    }

    class FireState: IState {}
    class FireEntity : IEntity<FireState>
    {
        public FireState Get() {}
        public void Set(FireState model) {}
    }
}

I would like to use the syntax of RepositoryB<T> but as you can see it the implicit conversion doesn't work like that.

I cannot get my head around how to cheat the compiler and get the desired syntax.

Any workarounds?

P.S. Obviously this is an excerpt of the real code and I cannot use Covariant out parameters for T

Cristian E.
  • 3,116
  • 7
  • 31
  • 61
  • I think you can do this with the `in` keyword? https://msdn.microsoft.com/en-us/library/dd469484.aspx – Adam Schiavone Mar 15 '17 at 23:09
  • 1
    This is just another "I want variance features when they aren't safe" question. See the marked duplicate for one of the many explanations on Stack Overflow describing why what you want to do isn't safe, and so you should not be allowed to do it. Without more specifics, it's impossible to actually _answer_ the question, but it will have to start with you fixing the basic problem that you are trying to stuff the wrong type into a spot where doing so would be unsafe. – Peter Duniho Mar 15 '17 at 23:13
  • @PeterDuniho The linked question has provided great explanation to my confusion, and reasoning behind. Thank you! – Cristian E. Mar 16 '17 at 08:33

0 Answers0