我正在尝试为我的老板创建一个小概念验证应用程序,但是我创建的代码模拟他试图启动的代码不起作用。
for (int i = 0; i < 5000; i++)
{
((IList<string>) obj2.Stuff).Add("Iteration " + i.ToString());
}
我试图在一行中将其全部删除,因为这是他们的代码在我们正在开发的框架中看起来的样子。 Anywho当上面的代码执行时,我得到一个运行时错误,说“Collection是固定大小的”。当我尝试转换为List而不是IList时,我得到一个InvalidCastException,说“无法将类型'System.String []'的对象转换为'System.Collections.Generic.List`1 [System.String]' 。“
任何人都有任何想法如何我可以拉出一个单线程序来向IEnumerable添加一个项目,或者帮我找出解决这两个错误的方法?提前谢谢。
编辑(4/19/2011美国东部时间上午10:49) 我正在添加更多代码来帮助人们 - 可能应该早点完成。遗憾。
的Program.cs:
#region Cast Test
Class1 obj2 = new Class1();
obj2.Stuff = Enumerable.Empty<string>();
Console.WriteLine("Cast - Start Time: " + 0 + "ms");
Stopwatch stopwatch2 = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 5000; i++)
{
((IList<string>) obj2.Stuff).Add("Iteration " + i.ToString());
}
stopwatch2.Stop();
Console.WriteLine("Cast - Stop Time: " + stopwatch2.ElapsedMilliseconds.ToString() + "ms");
#endregion
的Class1.cs:
public class Class1
{
private IEnumerable<string> stuff;
public IEnumerable<string> Stuff
{
get { return stuff; }
set { stuff = value; }
}
}
答案 0 :(得分:2)
C#中的数组具有固定大小。您无法向其添加项目。
答案 1 :(得分:2)
您无法将string[]
转换为IList<string>
,因为string[]
未实现该接口。您需要先创建一个实现IList<string>
的对象:
List<string> list = obj2.Stuff.ToList();
for (int i = 0; i < 5000; i++)
{
list.Add("Iteration " + i.ToString());
}
答案 2 :(得分:1)
为什么要在for循环中进行转换?虽然每个IList都是IEnumerable,但不是每个IEnumerable都是IList。您可以使用ToList扩展方法将IEnumerable复制到新列表。 (请确保using System.Linq;
)
此外,在此示例中,不需要for循环:
var list = obj2.Stuff.ToList();
new list.AddRange(Enumerable.Range(0, 5000).Select(i => "Iteration " + i.ToString()));
答案 3 :(得分:0)
IEnumerable
并未提供与IList
相同的功能。除非Stuff
是IEnumerable
IList
,否则您的代码将无效。
第一个合同只承诺你可以一次迭代一个元素。它永远不会声明你可以添加新的元素。
当且仅当在运行时,您的可枚举对象也满足IList
接口时,您才能将其关闭。
答案 4 :(得分:0)
您无法调用Add
,因为obj2.Stuff
似乎是一个数组,并且数组具有固定大小,如错误消息所示。
答案 5 :(得分:0)
类型System.String[]
是一个字符串数组,它实现IEnumerable<string>
但不是一个List<string>
。阵列具有固定长度。你为什么需要一行?
答案 6 :(得分:0)
将obj2.Stuff的类型更改为StringCollection或List。在.NET中,数组具有固定长度,您无法向它们添加新对象,因此请使用集合。
答案 7 :(得分:0)
由于obj2.Stuff
是一个字符串数组,因此无法执行您要执行的操作。无法调整数组大小,因此无法向其中添加项目。
如果你可以用另一个数组替换obj2.Stuff
中的数组,你可以从数组中获取数据并从中生成一个列表,将项添加到列表中,从列表中获取数据并创建一个数组从中,并使用它来替换原始数组:
List<string> items = new List<string>(obj2.Stuff);
for (int i = 0; i < 5000; i++) {
items.Add("Iteration " + i.ToString());
}
obj2.Stuff = items.ToArray();
如果obj2.Stuff
属性是只读的,那么除非将基础实现从数组更改为可以添加项目的集合,否则无法向其添加任何内容。
答案 8 :(得分:0)
在对上述答案之一的评论中,您说“我试图避免复制列表。”
您正在尝试将数据添加到基础类型为IEnumerable<T>
的对象。但是IEnumerable
对象不是实际的容器,它是一个接口。您无法向界面添加内容。但是您可以为其分配另一个实现该接口的对象。
因此,要使用上面的foson示例,您可以这样做:
obj2.Stuff = Enumerable.Range(0, 5000).Select(i => "Iteration " + i.ToString());
请注意,当此代码执行时,实际上没有发生。在实际迭代obj2.Stuff
之前,不会创建任何对象。当发生这种情况时,将调用LINQ中的方法,这些方法一次创建一个对象并将它们返回到迭代器循环。
但这里没有涉及实际的存储设备。您可以迭代obj2.Stuff
,除非您因此将每个整数添加到其他内容中,否则它们将在下一次迭代中消失。
这里的基本要点是你不能在IEnumerable
中存储东西,而是IEnumerable
是一种按顺序返回对象的方法,可以来自列表构造,也可以来自函数生成一个序列。