gpt4 book ai didi

c# - 如何创建派生类的嵌套列表

转载 作者:行者123 更新时间:2023-11-30 18:45:31 25 4
gpt4 key购买 nike

我正在编写一个应用程序来处理 WMI 对象。我有一个 ComputerList<Component>属性(property),正在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);
}

它工作正常,直到我意识到我想将每个组件都视为一个 List 本身,因为我需要将多个显示器和/或其他多个设备分开,所以我相应地更改了我的属性和方法:

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反对 List<Component> .

最佳答案

具体回答你的问题:

I don't understand why can't I add a List<Monitor> object to a List<List<Component>>, while I can add a Monitor object to a List<Component>.

这与询问为什么不能分配 List<Derived> 相同到 List<Base>其中 Derived : Base .

某些语言确实允许这样做,但 C# 不允许。让我们来看看原因。

考虑这些类:

class Animal
{
}

class Cat : Animal
{
public void Meow() {}
}

class Dog : Animal
{
public void Bark() { }
}

现在假设你有一个狗的列表:

List<Dog> dogs = new List<Dog> {new Dog()};

您不得执行以下操作:

List<Animal> animals = dogs;  // Not allowed - let's pretend it is!

好吧,让我们假设上面的代码行编译通过了。执行后,animals列表将引用 dogs ,这是一个 List<Dog> .记住这个重要的事实!

现在让我们执行以下操作:

animals.Add(new Cat());

看起来不错吧?没有。我们刚刚添加了一个 Catdogs ,现在包含两个元素;一个Cat和一个 Dog .

现在如果我们做 dogs[1].Bark(); 会发生什么?

答案是程序会在运行时崩溃,因为猫不会叫!当然,这实际上不可能发生,因为您不允许这样做 List<Animal> animals = dogs; .


可能的解决方案?

有一个 IReadOnlyList<T> interface你可以用它来代替 IList<T> :

IReadOnlyList<Animal> animals = dogs; // Compiles OK.

这是允许的,因为它是这样声明的:

public interface IReadOnlyList<out T> : IReadOnlyCollection<T>, 
IEnumerable<T>, IEnumerable

out T 指定接口(interface)为 covariant .

因为 IReadOnlyList不允许修改,有可能支持协变。

关于c# - 如何创建派生类的嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44675115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com