【发布时间】:2018-07-13 12:15:54
【问题描述】:
TL;DR:
如果 List
我收到“无法将类型 'Foo' 隐式转换为 'Bar' 的错误。存在显式转换(您是否缺少强制转换?)”
代码如下:
public interface IAmAHierarchyNode<IdType> {
IdType Id {
get;set;
}
ICollection<IAmAHierarchyNode<IdType>> Children {
get;
}
IAmAHierarchyNode<IdType> Parent {
get;set;
}
}
public class Network : IAmAHierarchyNode<Guid> {
public List<Facility> Facilities
{
get;set;
}
// This is where it's making me do an explicit conversion. But why?
public ICollection<IAmAHierarchyNode<Guid>> Children => Facilities;
public IAmAHierarchyNode<Guid> Parent {
get => throw new InvalidOperationException ();
set => throw new InvalidOperationException ();
}
}
public class Facility : IAmAHierarchyNode<Guid> {
public Network Network {
get;set;
}
public Guid NetworkId {
get;set;
}
public ICollection<IAmAHierarchyNode<Guid>> Children {
get => throw new NotImplementedException ();
}
public IAmAHierarchyNode<Guid> Parent {
get => Network;
set => throw new NotImplementedException ();
}
}
这是我迄今为止在研究中发现的:
This SO question 是我找到的最接近的。那里的第二个答案说
如果类型 T1 和 T2 相同,则只能将 List
转换为 ICollection 。
所以我正在从 List
可悲的是,this SO question 是 OP 的拼写错误。 This one 指的是显式接口实现,那里的答案会让我认为我不应该有问题。
【问题讨论】:
-
老实说,过于混杂的隐式转换是不好的。强类型化是你最大的朋友。如果您没有,请查看此处的 PHP 和 Javascript 示例:sandraandwoo.com/2015/12/24/… 曾经在 PHP 中实际编程过一次,我希望我有很强的类型化。
-
编译器一定认为存在丢失信息的风险,我前段时间也有同样的问题,但阅读了docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/… 并决定不发布,因为无论如何强烈建议使用强类型
-
这里我们实际上有一个演员表(列表到 ICollection)和一个泛型的“方差”机制在工作(IAmAHierarchyNode 的设施)。而且我猜编译器只是不敢尝试同时进行强制转换和方差更改。
-
"如果类型 T1 和 T2 相同,您只能将 List
转换为 ICollection 。" - “所以我从 List<Facility>转换为ICollection<IAmAHierarchyNode>” - 它们不一样。虽然Facility可能是IAmAHierarchyNode,但IAmAHierarchyNode不一定是Facility。这就是为什么它们不一样并且引用不适用的原因。 -
“我的 Facility 类实现了 IAmAHierarchyNode,所以我不明白为什么它们不会被认为是相同的”——在你引用的帖子中,这个词“相同”用于表示完全相同。不是 OOP 意义上的“is a”,而是字面上的完全相同的类型。现在有例外,对接口使用泛型类型变化,但这些例外不适用于您的示例。 许多 现有的关于 Stack Overflow 讨论泛型类型差异的问题和答案已经完全涵盖了您的问题。
标签: c#