Cannot convert Generic Class to Generic Interface, why?

家住魔仙堡 提交于 2019-12-13 01:38:39

问题


I have an IRepository interface that inherits from IRepository<TObject>. I also have a SqlRepository class that inherits from SQLRepository<TObject>, which in turn implements IRepository<TObject>. Why can't I instantiate a instance of SqlRepository as an IRepository?

public class MyObject : IObject {
    ...
}

public interface IRepository<TObject> where TObject : IObject, new() {
    ...
}

public interface IRepository : IRepository<MyObject> { }

public class SqlRepository<TObject> : IRepository<TObject> where TObject : IObject, new() {
    ...
}

public class SqlRepository : SqlRepository<MyObject> { }

public class Controller {
    private IRepository _repository;

    public Controller() {
        _repository = new SqlRepository();
    }
}

The example above fails when trying to assign a new SqlRepository to _repository in the Controller class, with the following error message.

Argument '1': cannot convert from 'SqlRepository' to 'IRepository'

Which basic principle of inheritance have I failed to grasp, please help.


回答1:


Because IRepository is an IRepository<MyObject> and not the other way around.

Basically:

SqlRepository is a SqlRepository<MyObject>
which is an IRepository<MyObject>.
To make that work, you should either inherit IRepository<TObject> from IRepository or make SqlRepository implement IRepository depending in your intention.

This issue is not generics-specific at all. Assume:

interface IMovable { }
interface IDrivable : IMovable { } 
class Ball : IMovable { }

It's obvious that Ball is not an IDrivable while it is an IMovable.




回答2:


SqlRepository implements IRepository<T>, not IRepository.




回答3:


I think you need to declare it like this:

private IRepository<MyObject> _repository;



回答4:


SqlRepository does not directly inherit from IRepository, it inherits from IRepository<MyObject>.

Try having SqlRepository inherit directly from IRepository.




回答5:


You can subclass generic types as well.

public class SqlObjectRepository : SqlRepository { ... }

But I don't think you can do that on the fly. It needs to be part of the definition of the object.



来源:https://stackoverflow.com/questions/1088845/cannot-convert-generic-class-to-generic-interface-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!