我有一个接口IJob,所有Job类都继承了它,我有一个通用的repo类,它将处理所有类型的IJob.
我面临的问题是我无法转换Repository<Job1>
为Repository<IJob>
即使Job1
是一种类型IJob
.
码
internal class Program
{
public interface IJob { }
public class Job1 : IJob { }
public class Job2 : IJob { }
public class Repository<TJob>
where TJob : IJob
{
public List<TJob> GetJobs()
{
return new List<TJob>();
}
}
private static void Main(string[] args)
{
IJob iJob = new Job1(); // Valid
Repository<IJob> repo = new Repository<Job1>(); // Not Valid
}
}
Run Code Online (Sandbox Code Playgroud)
有人能让我知道为什么在C#中这是不可能的,并且在C#泛型中是否还有其他规则类型转换?
Eir*_*son 18
如果你想要协方差,那么你必须为存储库引入一个通用接口,并将GetJobs
方法的返回类型更改为IEnumerable<TJob>
:
internal class Program
{
public interface IJob { }
public class Job1 : IJob { }
public class Job2 : IJob { }
public interface IRepository<out TJob> where TJob : IJob
{
IEnumerable<TJob> GetJobs();
}
public class Repository<TJob> : IRepository<TJob> where TJob : IJob
{
public IEnumerable<TJob> GetJobs()
{
return new List<TJob>();
}
}
private static void Main(string[] args)
{
IJob iJob = new Job1(); // Valid
IRepository<IJob> repo = new Repository<Job1>(); // Also valid
}
}
Run Code Online (Sandbox Code Playgroud)
有关协变和逆变的更多信息,请参见:https://msdn.microsoft.com/en-us/library/dd799517%28v=vs.110%29.aspx
nvo*_*igt 11
Repository<IJob> repo = new Repository<Job1>(); // Not Valid
Run Code Online (Sandbox Code Playgroud)
是的,因为它不是Repository<IJob>
.使用a Repository<IJob>
,此行有效:
repo.GetJobs().Add(new Job2());
Run Code Online (Sandbox Code Playgroud)
现在,使用a Repository<Job1>
,此行无效.它不会编译.
所以你得到的错误是正确的.一个Repository<Job1>
是不是一个Repository<IJob>
.