簡體   English   中英

為什么我無法使用接口將具體通用轉換為paremeter?

[英]Why I am unable to cast concrete generic to paremeter with interface?

我已經閱讀了許多與此相關的問題,也許這是重復但我仍然無法理解這個概念。 從我讀到的,這與協方差和逆變有關

我有這些接口和類:

public interface IBaseEntity
public interface IRepository<T> where T : IBaseEntity

public interface ITravelRequest : IBaseEntity
public interface IUser : IBaseEntity

public class TravelRequest : ITravelRequest
public class User:  IUser

我有這個控制器:

public TravelRequestsController(IRepository<ITravelRequest> repository, IRepository<IUser> userRepositor)

我試圖通過像這樣創建它們來注入存儲庫:

var travelRequestRepository = new Repository<TravelRequest>(context);
var userRepository = new Repository<User>(context);

var controller = new TravelRequestsController(travelRequestRepository, userRepository);

但我得到這個錯誤:

Error   4   Argument 1: cannot convert from
DAL.Repository<Elite.Models.TravelRequest.TravelRequest>' to
DAL.IRepository<Elite.Models.TravelRequest.ITravelRequest>' 

我該怎么做才能做到這一點?

更新 - 完整的IRepository

 public interface IRepository<T> where T : IBaseEntity
    {
        IEnumerable<T> AsQueryable();

        IList<T> GetAll();
        IList<T> Find(Expression<Func<T, bool>> predicate);
        T Single(Expression<Func<T, bool>> predicate);
        T SingleOrDefault(Expression<Func<T,bool>> predicate);
        T First(Expression<Func<T, bool>> predicate);
        T GetById(int id);

        T Create();
        void Add(T entity);
        void Delete(T entity);
        void Update(T entity);
        void Save();
    }

我可以更改控制器簽名,但我的最終目標是使用Moq等測試它。

假設IRepository<T>具有Insert(T request)方法。 Repository<T>將此方法實現為Insert(T request) ,這意味着Repository<TravelRequest>具有Insert(TravelRequest request)方法簽名, 但它沒有Insert(ITravelRequest request)簽名。

要擺脫錯誤,請使用out關鍵字聲明接口。

public interface IRepository<out T> where T : IBaseEntity
{}

我能夠成功編譯以下代碼。

    static void Main(string[] args)
    {
        var travelRequestRepository = new Repository<TravelRequest>();
        var userRepository = new Repository<User>();
        test(travelRequestRepository,userRepository);
        Console.ReadLine();


    }

    static void test(IRepository<ITravelRequest> repository, IRepository<IUser> userRepositor)
    {

    }


    public interface IBaseEntity{}

    public interface IRepository<out T> where T : IBaseEntity
    {}

    public class Repository<T>:IRepository<T> where T:IBaseEntity
    {

    }

    public interface ITravelRequest : IBaseEntity
    {}

    public interface IUser : IBaseEntity
    {}

    public class TravelRequest : ITravelRequest
    {}

    public class User : IUser
    { }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM