我有一个自定义类CurvePoint
,我使用DrawCurve
我编写了一个转换例程来将CurvePoint转换为Point,但是我收到了错误 源阵列中至少有一个元素无法转换为目标数组类型。当我尝试在Arraylist中使用.ToArray方法时
我可以使用代码将对象强制转换:
Point f = new CurvePoint(.5F, .5F, new Rectangle(0, 0, 10, 10));
但如果在使用
时失败
Point[] Plots=(Point[])_Data.ToArray(typeof(Point));
(其中_Data是一个填充了5个CurvePoint对象的ArrayList)
以下是完整代码:
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%");
}
}
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%");
}
}
有人可以说如何修复代码吗?
答案 0 :(得分:2)
首先,我将您的ArrayList更改为强类型通用列表List<CurvePoint>
。然后,要获取Point数组,可以执行此代码。
Point[] Plots = _Data.Select(obj => (Point)obj).ToArray();
如果将其保留为ArrayList,您仍然可以使用以下代码执行此操作:
Point[] Plots = (from CurvePoint obj in _Data select (Point)obj).ToArray();
// or
Point[] Plots = _Data.Cast<CurvePoint>().Select(obj => (Point)obj).ToArray();
编辑:最后,如果您遇到了ArrayList 和,那么您没有LINQ,那么您可以采用“长”方式。
Point[] Plots = new Point[_Data.Count];
for (int i = 0; i < _Data.Count; i++)
{
Plots[i] = (Point)(CurvePoint)_Data[i];
}
答案 1 :(得分:1)
你不能这样做的原因是你的ArrayList通过对对象的引用包含点。因此,没有用户定义的对象转换(即使它是对CurvePoint的引用,它确实有定义的转换)到你的Point类型。
以下修复程序将起作用(.NET 3.5 +):
Point[] Plots = _Data
.OfType<CurvePoint>()
.Select(cp => (Point)cp)
.ToArray();