所以我已经编程了大约6个月,因为它是休息的,我很无聊并玩弄东西。我再次讨论了数组的概念并制作了一个数组,它产生了50个randoms数字,并使用插入排序对它们进行排序。然后我开始搞乱字符串数组。 string[] array = new string[] { "Ultima Online", "Everquest", "Baldur's Gate", "Diablo I"};
是我的字符串数组。为了让它显示整个字符串,我使用了一个链表(我不确定是否必须这样做,我试图将其转换为无效,即Convert.ToString(数组)失败)。所以我有这个
static void Main(string[] args)
{
string[] array = new string[] { "Ultima Online", "Everquest", "Baldur's Gate", "Diablo I"};
List<string> list = new List<string>(array);
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
}
这将显示整个阵列。然后我想如果我想删除或添加一些内容。所以,我将list.RemoveAt(2);
放在Console.Writeline(list[i]);
但这确实是我没想到的。它会删除列表中第二个点之后的所有内容。所以我假设RemoveAt()将始终删除指示的值之后的所有内容。
但是,list.Remove(2);
会出错。 1.参数1:无法从'int'转换为'string'然后2.最好的重载方法匹配... etc ..参数。
我的演员再次无效。所以,我回到了RemoveAt,想了一下。出于某种原因,我想如果我使用等效的if语句,它会起作用,而且确实如此。
static void Main(string[] args)
{
string[] array = new string[] { "Ultima Online", "Everquest", "Baldur's Gate", "Diablo I" };
List<string> list = new List<string>(array);
for (int i = 0; i < list.Count; i++)
{
if (i == 2)
{
list.RemoveAt(2);
}
Console.WriteLine(list[i]);
}
所以,我的问题是: 为什么异常发生在Remove()而不是RemoveAt()。 为什么if语句有效?我在黑暗中拍摄它并且它有效,我可以理解为什么它有效,但不是为什么简单的RemoveAt()不起作用。 最后,有没有比链表更好的转换方式?
感谢所有回答这些问题的人。我是编程新手,我正在尝试理解在我的书和MSDN.com以及DotPearl上飞过我的一些概念...
答案 0 :(得分:7)
RemoveAt
仅删除该索引的元素。它不删除它后面的所有元素。
除非....你把它放在一个循环中。
你做了什么。
所以你的循环做到了这一点:
因为这个“有效”:
for (.....; i < list.Count; ..... )
^-- this ----^
基本上,你的循环和列表看起来像这样:
您在枚举时更改了列表,并在每次迭代时更改了 。
list.Remove(2)
不起作用的原因是:
list.RemoveAt(x)
指定索引,并删除该索引处的元素list.Remove(x)
指定一个值,列表中第一个具有该值的元素将被删除现在在这种情况下你已经说过列表是一个字符串列表,你要求它删除一个整数。 C#/ .NET不允许这样的恶作剧,因此在你允许运行程序之前告诉你这个问题。
有关详细信息,请查看以下文档:
答案 1 :(得分:3)
Remove
采用T
类型的参数,该参数对应于您要删除的对象。在您的实例中,Remove
采用string
参数,该参数应与列表中的某个字符串项相对应(例如Ultima Online
)。
RemoveAt
获取一个int,该int对应于要删除的列表中项目的 index 。删除之后,所有内容都会“移位”,因此索引3处的内容现在位于索引2.当您的循环再次经过RemoveAt(2)
时,它会删除现在的项目指数2.
答案 2 :(得分:2)
RemoveAt
按索引工作。 Remove
正在使用等式的类型定义。你有一个List<string>
,类型是string
,字符串逐个字符比较来确定相等,删除你需要做的字符串;
list.Remove("Diablo I");
Dave Zych的回答很好地解释了RemoveAt
摆脱除第一项之外的所有事情的问题,所以我不会深入探讨。
我会谈到您转换为列表并使用术语“链接列表”。首先,.NET中的List<T>
绝不是链表。它在某些方面表现得像一个,但它由数组支持。您无需转换为它。要打印阵列,您可以执行以下任一操作;
for (int i = 0; i < array.Length; i++)
Console.WriteLine(array[i]);
或
Console.WriteLine(String.Join("\n", array));
您可以轻松“删除”某个项目;
array[i] = null;
假设你没有在该行之前的其他地方做过string temp = array[i]
这样的事情,你会将对该字符串的最终现有引用设置为null
,这基本上将队列放入GC中。
答案 3 :(得分:2)
为什么异常发生在Remove()但不是RemoveAt()?
您获得异常Argument 1: cannot convert from 'int' to 'string'
,因为方法签名为List<T>.Remove<T>(T)
。它期望string
..并且你给它一个数字。
为什么这个if语句有效?
因为您可以完全自由地将数字与数字进行比较。再次,您在这里使用了RemoveAt
..这需要一个数字..而且您已正确提供了一个。
此外,List<T>
不是链接列表。它实际上是一个由数组支持的列表。一个重要的区别imo。