0

I have a custom class CurvePoint which I define a set of data items to draw on the screen using DrawCurve

I written a cast routine to convert CurvePoint to Point, but I am getting the error At least one element in the source array could not be cast down to the destination array type. when I try to use the .ToArray method in an Arraylist

I can cast the objects fine using the code:

Point f = new CurvePoint(.5F, .5F, new Rectangle(0, 0, 10, 10));

but if fails when using

Point[] Plots=(Point[])_Data.ToArray(typeof(Point));

(where _Data is an ArrayList which is populated with 5 CurvePoint objects)

Here is the full code:

public partial class Chart : UserControl
{
    ArrayList _Data;
    public Chart()
    {
        InitializeComponent();
        _Data = new ArrayList();
        _Data.Add(new CurvePoint(0f, 0f,this.ClientRectangle));
        _Data.Add(new CurvePoint(1f, 1f, this.ClientRectangle));
        _Data.Add(new CurvePoint(.25f, .75f, this.ClientRectangle));
        _Data.Add(new CurvePoint(.75f, .25f, this.ClientRectangle));
        _Data.Add(new CurvePoint(.5f, .6f, this.ClientRectangle));
    }
    private void Chart_Paint(object sender, PaintEventArgs e)
    {
        _Data.Sort();
        e.Graphics.FillEllipse(new SolidBrush(Color.Red),this.ClientRectangle);
        Point[] Plots=(Point[])_Data.ToArray(typeof(Point));
        e.Graphics.DrawCurve(new Pen(new SolidBrush(Color.Black)), Plots);
    }
}
public class CurvePoint : IComparable
{
    public float PlotX;
    public float PlotY;
    public Rectangle BoundingBox;
   public CurvePoint(float x, float y,Rectangle rect)
    {
        PlotX = x; PlotY = y;
        BoundingBox = rect;
    }

    public int CompareTo(object obj)
    {
        if (obj is CurvePoint)
        {
            CurvePoint cp = (CurvePoint)obj;
            return PlotX.CompareTo(cp.PlotX);
        }
        else
        { throw new ArgumentException("Object is not a CurvePoint."); }
    }
    public static implicit operator Point(CurvePoint x)
    {
        return new Point((int)(x.PlotX * x.BoundingBox.Width), (int)(x.PlotY * x.BoundingBox.Height));
    }
   public static implicit operator string(CurvePoint  x)
    {
        return x.ToString();
    }
   public override string ToString()
    {
        return "X=" + PlotX.ToString("0.0%") + " Y" + PlotY.ToString("0.0%");
    }

}

Can anyone sujest how to fix the code?

2 Answers 2

2

First, I would change your ArrayList to a strongly typed generic list, List<CurvePoint>. Then, to get your Point array, you can perform this code.

Point[] Plots = _Data.Select(obj => (Point)obj).ToArray();

If you leave it as an ArrayList, you can still do it using this code:

Point[] Plots = (from CurvePoint obj in _Data select (Point)obj).ToArray();
// or
Point[] Plots = _Data.Cast<CurvePoint>().Select(obj => (Point)obj).ToArray();

Edit: Finally, if you're stuck with ArrayList and you do not have LINQ, you can do this the "long" way.

Point[] Plots = new Point[_Data.Count];
for (int i = 0; i < _Data.Count; i++)
{
    Plots[i] = (Point)(CurvePoint)_Data[i];
}
Sign up to request clarification or add additional context in comments.

Comments

1

The reason you can't do it is that your ArrayList contains points through references to object. Therefore there's no user-defined cast from object (even though it's a reference to CurvePoint, which does have the cast defined) to your Point type.

The following fix will do the trick (.NET 3.5+):

        Point[] Plots = _Data
            .OfType<CurvePoint>()
            .Select(cp => (Point)cp)
            .ToArray();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.