C# 索引到ArrayList的结果的InvalidCastException
我有一个ArrayList,里面有一堆点,我想在它们上面循环,所以我使用以下代码:C# 索引到ArrayList的结果的InvalidCastException,c#,visual-studio,visual-studio-2008,C#,Visual Studio,Visual Studio 2008,我有一个ArrayList,里面有一堆点,我想在它们上面循环,所以我使用以下代码: for (int i = 0; i < currentClicks.Count; i++) { if (i > 0) // Skip the first click { clickPos = currentClicks[i]; prevPos = currentClicks[i - 1]; } } 为什么会这样?我将clickPos和prevP
for (int i = 0; i < currentClicks.Count; i++)
{
if (i > 0) // Skip the first click
{
clickPos = currentClicks[i];
prevPos = currentClicks[i - 1];
}
}
为什么会这样?我将clickPos
和prevPos
定义为:
private System.Drawing.Point clickPos;
private System.Drawing.Point prevPos;
编辑
当我注释掉时,单击pos
和prevPos
行并添加
MessageBox.Show(currentClicks[i].GetType().ToString());
消息框显示System.Drawing.Point
请尝试以下操作:
for (int i = 1; i < currentClicks.Count; i++)
{
clickPos = (System.Drawing.Point)currentClicks[i];
prevPos = (System.Drawing.Point)currentClicks[i - 1];
}
for(int i=1;i
更好的解决方案可能是使用一个通用列表,一个
列表
,这样您就根本不需要强制转换。您应该使用通用列表
而不是数组列表
如果坚持使用ArrayList,则在检索对象时需要将对象强制转换到点
:
clickPos = (Point)currentClicks[i];
你为什么不从1开始呢
for (int i = 1; i < currentClicks.Count; i++)
{
clickPos = (System.Drawing.Point)currentClicks[i];
prevPos = (System.Drawing.Point)currentClicks[i - 1];
}
for(int i=1;i
数组列表
不是强类型的。它们基本上是对象的IList
因此,需要将对arraylist元素的引用转换为已知的类型
clickPos = (Point)currentClicks[i];
prevPos = (Point)currentClicks[i - 1];
我强烈建议使用列表
而不是数组列表
。这将为您提供一个强类型的点列表,并消除强制转换引用的要求
通用列表
也提供与阵列列表
完全相同的功能,但通常性能更好
性能注意事项
在决定是否使用列表或
ArrayList类,这两个类都具有
类似的功能,记住
列表类在大多数情况下性能更好
案例和类型安全。如果是推荐人
类型用于列表的类型T
类,这两个类的行为
是一样的
Nick的代码可以使用,或者您可以尝试使用:
ArrayList
ArrayList实现IEnumerable,这意味着它总是返回System.ObjectArrayList
实现IEnumerable并将始终返回T。一个ArrayList
包含对对象的引用,并且您正试图将这些对象隐式强制转换为点。如Nick所示,您可以显式强制转换,也可以使用通用的列表
,这是我的建议:
List<Point> currentClicks = new List<Point>();
// add your points
List currentlicks=新建列表();
//添加您的观点
使用泛型列表(在2.0中添加到.NET,如所述)允许您以更安全的方式处理对象,而无需运行时强制转换。如果您使用的是.NET 2.0或更高版本,则永远不要使用ArrayList
、Hashtable
,或任何其他非通用构造。除非您被困在.NET 1.1上或无法控制列表的创建,否则使用列表会更好
ArrayList要求使用explict类型转换来获取成员,除非您只想将其用作对象,所以需要这样做
clickPos = (Point)currentClicks[i];
prevPos = (Point)currentClicks[i - 1];
关于编辑:您知道ArrayList保存点,运行时知道ArrayList保存点(因此是.GetType()
结果),但编译器不知道ArrayList保存点。您需要在那里进行强制转换以满足编译器的要求
但实际上,唯一正确的解决方法是将其更改为通用的列表
在哪里定义currentClicks?Form1.Designer.cs;给出错误的代码在Form1.csDear God中,是的;使用列表+1.在VS2008中使用ArrayList的唯一原因是为了与设置文件兼容。此外,一旦获得了列表,请使用foreach循环而不是for循环对其进行迭代。ArrayList是非泛型的。您的意思是建议列出?这将返回强类型的T
,而不需要强制转换对象。=p好主意。我来自Ruby背景,所以我不习惯所有这些for循环
clickPos = (Point)currentClicks[i];
prevPos = (Point)currentClicks[i - 1];