C#泛型之间是否有类型转换规则?

Uma*_*ran 18 c# generics

我有一个接口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>.