如何修复这个错误?无效方差:类型参数“T”;必须始终有效

发布于 2024-12-04 19:11:03 字数 1256 浏览 1 评论 0 原文

我在编译时收到以下错误消息:

“无效方差:类型参数 'T' 必须在 'ConsoleApplication1.IRepository.GetAll()' 上始终有效。'T' 是协变的。”

下面是我的代码:

 class Program
{

    static void Main(string[] args)
    {
        IRepository<BaseClass> repository;

        repository = new RepositoryDerived1<Derived1>();

        Console.ReadLine();
    }
}

public abstract class BaseClass
{

}

public class Derived1 : BaseClass
{

}

public interface IRepository<out T> where T: BaseClass, new()
{
    IList<T> GetAll();
}

public class Derived2 : BaseClass
{

}

public abstract class RepositoryBase<T> : IRepository<T> where T: BaseClass, new()
{
    public abstract IList<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T: BaseClass, new()
{
    public override IList<T> GetAll()
    {
        throw new NotImplementedException();
    }
}

我需要的是能够像这样使用上面的类:

IRepository存储库;

RepositoryBase 存储库;

然后我希望能够分配这样的内容:

repository = new RepositoryDe​​rived1();

但它在 IRepository 类上给出了编译时错误。

如果我从 IRepository 类中删除“out”关键字,则会出现另一个错误:

“RepositoryDe​​rived1”无法转换为“IRepository”。

为什么以及如何解决它?

谢谢

I'm having the below error message at compile time:

"Invalid variance: The type parameter 'T' must be invariantly valid on 'ConsoleApplication1.IRepository.GetAll()'. 'T' is covariant."

and the below is my code:

 class Program
{

    static void Main(string[] args)
    {
        IRepository<BaseClass> repository;

        repository = new RepositoryDerived1<Derived1>();

        Console.ReadLine();
    }
}

public abstract class BaseClass
{

}

public class Derived1 : BaseClass
{

}

public interface IRepository<out T> where T: BaseClass, new()
{
    IList<T> GetAll();
}

public class Derived2 : BaseClass
{

}

public abstract class RepositoryBase<T> : IRepository<T> where T: BaseClass, new()
{
    public abstract IList<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T: BaseClass, new()
{
    public override IList<T> GetAll()
    {
        throw new NotImplementedException();
    }
}

What I would need is to be able to use the above class like this:

IRepository repository;

or

RepositoryBase repository;

Then I'd like to be able to assign something like this:

repository = new RepositoryDerived1();

But it gives compile time error on the IRepository class.

If I remove the "out" keyword from the IRepository class, it gives me another error that

"RepositoryDerived1" can not be converted to "IRepository".

Why and how to fix it?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一抹淡然 2024-12-11 19:11:03

IList 不是协变的。如果将 IList 更改为 IEnumerable,并从 IRepository: new() 约束T> (因为抽象基类不满足这一点)它将起作用:

public interface IRepository<out T> where T : BaseClass
{
    IEnumerable<T> GetAll();
}

public abstract class RepositoryBase<T> : IRepository<T> where T : BaseClass, new()
{
    public abstract IEnumerable<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T : BaseClass, new()
{
    public override IEnumerable<T> GetAll()
    {
        throw new NotImplementedException();
    }
}

IList<T> is not covariant. If you change the IList<T> to IEnumerable<T>, and remove the : new() constraint from IRepository<out T> (as the abstract base class doesn't satisfy that) it'll work:

public interface IRepository<out T> where T : BaseClass
{
    IEnumerable<T> GetAll();
}

public abstract class RepositoryBase<T> : IRepository<T> where T : BaseClass, new()
{
    public abstract IEnumerable<T> GetAll();
}

public class RepositoryDerived1<T> : RepositoryBase<T> where T : BaseClass, new()
{
    public override IEnumerable<T> GetAll()
    {
        throw new NotImplementedException();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文