gpt4 book ai didi

c# - 如何将通用集合转换为通用祖先集合?

转载 作者:太空宇宙 更新时间:2023-11-03 17:21:54 25 4
gpt4 key购买 nike

考虑 Label 列表:

Collection<Label> labels = new Collection<Label>();

现在我想将其转换为 Controls 的集合:

public void ScaleControls(ICollection<Control> controls) {}

我会尝试调用:

ScaleControls(labels);

但这不能编译。

ScaleControls((ICollection<Control>)labels);

编译,但在运行时崩溃。

ICollection<Control> controls = (ICollection<Control>)labels;
ScaleControls(c);

编译,但在运行时崩溃。

有没有办法传递对象的通用列表?


另一种方法是放弃通用列表,并使用类型化列表:

public class ControlList : Collection<Control>
{
}

pubic void InvalidateControls(ControlList controls)
{
}

但这意味着必须改造所有使用泛型的代码。

最佳答案

你不能施放它;你必须自己转换它。

InvalidateControls(new List<Control>(labels));  //C# 4 or later

你的问题是 ICollection<T>不是协变的。 ICollection 不是协变的原因是为了防止像这样的方法是邪恶的:

void AddControl(ICollection<Control> controls, Control control)
{
controls.Add(control);
}

为什么那是邪恶的?因为如果 ICollection 是协变的,该方法将允许您将 TextBox 添加到标签列表中:

AddControl(new List<Label>(), new TextBox());

List<Control>有一个采用 IEnumerable<Control> 的构造函数.为什么我们可以通过labels在?因为IEnumerable<T>是协变的:你不能将任何东西放入 IEnumerable<T> ;你只能把东西拿出来。因此,您知道您可以处理从 IEnumerable<T> 中检索到的任何内容作为 T(当然)或其任何基本类型

编辑

我刚刚注意到您使用的是 .Net 3.5。在这种情况下,IEnumerable<T>不是协变的,您将需要更多代码来转换集合。像这样:

ICollection<T> ConvertCollection<T, U>(ICollection<U> collection) where U : T
{
var result = new List<T>(collection.Count);
foreach (var item in collection)
result.Add(item);
}

关于c# - 如何将通用集合转换为通用祖先集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8810370/

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