【问题标题】:Assign generic type class implementing interface to generic type being interface将实现接口的泛型类型类分配给作为接口的泛型类型
【发布时间】:2020-03-30 15:04:23
【问题描述】:

我不确定我的问题是否清楚,所以我将通过代码说明:

基本上我有一个加载器接口,泛型类型是一个接口。 在这里,Cat 和 Dog 都实现了 IAnimal。

private readonly IAnimalLoader<Cat> _catLoader;
private readonly IAnimalLoader<Dog> _dogLoader;

private IAnimalLoader<IAnimal> animalLoader;

public AnimalService(IAnimalLoader<Cat> catLoader,
                     IAnimalLoader<Dog> dogLoader)
{
    _catLoader = catLoader;
    _dogLoader = dogLoader;
}

问题在于尝试将任一加载器分配给 animalLoader:

if (animal == AnimalType.Cat)
{
    animalLoader = _catLoader;
}
else
{
    animalLoader = _dogLoader;
}

C# 抱怨 没有从 CatIAnimal 的隐式转换,即使它实现了它。似乎没有演员可以解决这个问题。

知道我做错了什么吗?

编辑:这里是 IAnimalLoader 澄清

public interface IAnimalLoader<T> where T : IAnimal
{
    IQueryable<T> GetAllQueryable();
    Task<T> GetAsync(string id);
}

【问题讨论】:

  • 另外,你能告诉我们IAnimalLoader的代码
  • @Sean 问题已更新详细信息
  • 为什么需要将_catLoader分配给animalLoader?当您同时存储两者时,为什么不直接调用它们呢?
  • @Sean 有它——基本上,问题是你不能在IAnimalLoader&lt;IAnimal&gt;IAnimalLoader&lt;Cat&gt; 之间来回切换,而不用关键字inout 这样它就知道由于类型不同会发生什么。如果类型不同并且没有这样的标记,C# 唯一能做的就是检查从一种类型到另一种类型的隐式转换,这解释了您看到的错误。查看 Sean 的链接以获取有关如何操作的更多信息。

标签: c# .net-core object-oriented-analysis


【解决方案1】:

虽然Cat 实现了IAnimal,但IAnimalLoader&lt;Cat&gt;IAnimalLoader&lt;IAnimal&gt; 没有这种关系,这就是错误消息的含义。

一般来说,转换成功需要将泛型参数标记为协变,语法为out TIIRC,否则,请查看C#语言参考关于泛型的方差。

更新(感谢下面的评论):在您的情况下,即使这是不可能的,因为其中一种类型 Task&lt;T&gt; 是不变的。只有接口可以标记为变体,类不能。

【讨论】:

  • 这里不能将T 声明为协变,因为Task&lt;T&gt; 是不变的
  • 感谢您的回答。所以我必须摆脱我的任务?
  • 除了你之外没有人能回答这个问题。如果该任务必须在那里,您可以将其隐藏在某个界面后面并制作该变体。不过可能会也可能不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 2016-10-16
  • 1970-01-01
  • 2015-01-18
  • 2021-05-05
相关资源
最近更新 更多