考虑以下列表Label:
Collection<Label> labels = new Collection<Label>();
Run Code Online (Sandbox Code Playgroud)
现在我想将其转换为以下集合Controls:
public void ScaleControls(ICollection<Control> controls) {}
Run Code Online (Sandbox Code Playgroud)
我会试着打电话:
ScaleControls(labels);
Run Code Online (Sandbox Code Playgroud)
但那不会编译.
ScaleControls((ICollection<Control>)labels);
Run Code Online (Sandbox Code Playgroud)
编译,但在运行时崩溃.
ICollection<Control> controls = (ICollection<Control>)labels;
ScaleControls(c);
Run Code Online (Sandbox Code Playgroud)
编译,但在运行时崩溃.
有没有办法传递对象的通用列表?
另一种方法是放弃通用列表,并使用类型化列表:
public class ControlList : Collection<Control>
{
}
pubic void InvalidateControls(ControlList controls)
{
}
Run Code Online (Sandbox Code Playgroud)
但这意味着所有使用泛型的代码都必须进行改造.
pho*_*oog 10
你不能施展它; 你必须自己转换它.
InvalidateControls(new List<Control>(labels)); //C# 4 or later
Run Code Online (Sandbox Code Playgroud)
你在这里的问题ICollection<T>是不协变.ICollection不协变的原因是为了防止这样的方法变得邪恶:
void AddControl(ICollection<Control> controls, Control control)
{
controls.Add(control);
}
Run Code Online (Sandbox Code Playgroud)
为什么那会是邪恶的?因为如果ICollection是协变的,该方法将允许您将TextBox添加到标签列表:
AddControl(new List<Label>(), new TextBox());
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8184 次 |
| 最近记录: |