【发布时间】:2017-06-21 21:29:27
【问题描述】:
我正在编写一个应用程序来处理 WMI 对象。我有一个带有List<Component> 属性的Computer 类,它是Component 一个抽象基类,所有派生类都来自该类,例如Monitor、ComputerUnit、Printer 等等。
考虑到 WMI 对象种类繁多,我第一次决定使用自定义 .NET 泛型(我是初学者),这就是代码 - 只是相关行:
public class Computer
{
public List<Component> ListOfComponents { get; set; }
}
public class Component
{
public NameSpaceBase[] WMI_ClassArray { get; set; }
}
public class Monitor : Component
{ }
public class ComputerUnit : Component
{ }
public static void Main()
{
Computer computer = new Computer(hostName);
Monitor monitor = computer.Get<Monitor>(new NameSpaceBase[] {
new WMI_Monitor() });
ComputerUnit computerUnit = computer.Get<ComputerUnit>(
new NameSpaceBase[] {
new WMI_Bios(),
new WMI_ComputerSystem() });
computer.ListOfComponents.Add(monitor);
computer.ListOfComponents.Add(computerUnit);
}
直到我意识到我想将每个组件都视为一个列表本身之前它工作得很好,因为我需要将多个监视器和/或其他多个设备分开,所以我相应地更改了我的属性和方法:
public class Computer
{
public List<List<Component>> ListOfComponents { get; set; }
}
public static void Main()
{
Computer computer = new Computer(hostName);
List<Monitor> monitor = computer.Get<Monitor>(new NameSpaceBase[] {
new WMI_Monitor() });
List<ComputerUnit> computerUnit = computer.Get<ComputerUnit>(
new NameSpaceBase[] {
new WMI_Bios(),
new WMI_ComputerSystem() });
computer.ListOfComponents.Add(monitor);
computer.ListOfComponents.Add(computerUnit);
}
但现在我在最后两行得到error CS1503: Argument 1: cannot convert from 'System.Collections.Generic.List<Machine.Components.Monitor>' to 'System.Collections.Generic.List<Machine.Components.Component>'。
我不明白错误在哪里,因为如果我注释最后两行,我可以看到 List 和 List 对象已正确创建、类型正确并填充了预期的数据。
故事的底线:我不明白为什么我不能将List<Monitor> 对象添加到List<List<Component>>,而我可以将Monitor 对象添加到@ 987654334@.
【问题讨论】:
-
这与协方差有关,但我不确定为什么它不起作用,因为 List
是协变的。 -
@rory.ap 因为协方差只与接口和委托有关
-
@rory.ap,不支持类中的协方差
-
啊,就是这样。正确的。所以把
Computer.ListOfComponents的类型从List<Component>改成IList<Component>。 -
另一种解决方案是,如果您使用 Component 类并将 (Child)Components 属性添加为
List<Component>。另请参阅Composite pattern。