开发者

InvalidCastException on Result of Indexing Into an ArrayList

开发者 https://www.devze.com 2022-12-19 23:44 出处:网络
I have an ArrayList filled with a bunch of Points and I want to loop over them, so I use this code: for (int i = 0; i < currentClicks.Count; i++)

I have an ArrayList filled with a bunch of Points and I want to loop over them, so I use this code:

for (int i = 0; i < currentClicks.Count; i++)
{
    if (i > 0) // Skip the first click
    {
        clickPos = currentClicks[i];
        prevPos = currentClicks[i - 1];
    }
}

and I get this error on the clickPos and prevPos lines:

Cannot implicitly convert type 'object' to 'System.Drawing.Point'.
An explicit conversion exists (are you missing a cast?)

Why is this? I have clickPos and prevPos defined as so:

private System.Drawing.Point c开发者_开发问答lickPos;
private System.Drawing.Point prevPos;

Edit

When I comment out the clickPos and prevPos lines and add

MessageBox.Show(currentClicks[i].GetType().ToString());

the message box says System.Drawing.Point


You should use the generic List<Point> instead of an ArrayList.

If you insist on using an ArrayList, you'll need to cast the objects to a Point when you retrieve them:

clickPos = (Point)currentClicks[i];


Try this:

for (int i = 1; i < currentClicks.Count; i++)
{
    clickPos = (System.Drawing.Point)currentClicks[i];
    prevPos = (System.Drawing.Point)currentClicks[i - 1];
}

A better solution could be using a generic list, a List<Point>, then you wouldn't need the cast at all.


ArrayLists are not strongly typed. They are basically an IList of object.

Because of this, you need to cast your references to the arraylist elements to the type that you know they are.

    clickPos = (Point)currentClicks[i];
    prevPos = (Point)currentClicks[i - 1];

I would strongly recommend using a List<Point> rather than an ArrayList. This will give you a strongly typed list of Points and remove the requirement for having to cast your references.

A generic List<T> also offers the exact same functionality as an ArrayList, but generally with better performance. From the documentation:

Performance Considerations

In deciding whether to use the List or ArrayList class, both of which have similar functionality, remember that the List class performs better in most cases and is type safe. If a reference type is used for type T of the List class, the behavior of the two classes is identical.


Why wouldn't you just start with 1?

for (int i = 1; i < currentClicks.Count; i++) 
{ 
         clickPos = (System.Drawing.Point)currentClicks[i];
        prevPos = (System.Drawing.Point)currentClicks[i - 1];
} 


Regarding your edit: you know the ArrayList holds points, and the runtime knows the ArrayList holds points (hence the .GetType() result), but the compiler does not know the arraylist holds points. You need a cast there to satisfy the compiler.

But really, the only correct way to fix this is to change it to a generic List<Point>.


Nick's code will work, or you could try using:

ArrayList<System.Drawing.Point>

The ArrayList implements IEnumerable, which means it always hands back System.Object. ArrayList<T> implements IEnumerable and will always hand back a T.


An ArrayList contains references to objects, and you're attempting to implicitly cast those objects to Points. You can either explicitly cast, as Nick shows, or use a generic List<T> instead, which is what I would recommend:

List<Point> currentClicks = new List<Point>();
// add your points

Using a generic List (added to .NET in 2.0, described here) allows you to work with objects in a much more type-safe manner, without runtime casts. If you're working with .NET 2.0 or greater, you should never use ArrayList, Hashtable, or any of the other non-generic constructs.


Unless you are stuck on .NET 1.1 or have no control over the creation of the list, you would be better off with List<Point>

the ArrayList requires that you use explict casts to get at the members unless you want to use them simply as object, so you need this

clickPos = (Point)currentClicks[i];
prevPos = (Point)currentClicks[i - 1];
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号