自定义class的一个参数被重写

One parameter of custom class is re-written

我有一个三角形的自定义 class:

[XmlRootAttribute(Namespace = "", IsNullable = false)]
[XmlType("Figure.Triangle")]
public class Triangle : Figure
{
    [XmlIgnore]
    public Point a { get; set; }
    [XmlIgnore]
    public Point b { get; set; }
    [XmlIgnore]
    public Point c { get; set; }

    [XmlElement("a")]
    public string aString
    {
        get { return a.X.ToString() + ';' + a.Y.ToString(); }
        set
        {
            if (String.IsNullOrWhiteSpace(value))
                return;
            string[] xmlArr = value.Split(';');
            this.a = new Point(Convert.ToInt32(xmlArr[0]), Convert.ToInt32(xmlArr[1]));
        }
    }

    [XmlElement("b")]
    public string bString
    {
        get { return b.X.ToString() + ';' + b.Y.ToString(); }
        set
        {
            if (String.IsNullOrWhiteSpace(value))
                return;
            string[] xmlArr = value.Split(';');
            this.b = new Point(Convert.ToInt32(xmlArr[0]), Convert.ToInt32(xmlArr[1]));
        }
    }

    [XmlElement("c")]
    public string cString
    {
        get { return c.X.ToString() + ';' + c.Y.ToString(); }
        set
        {
            if (String.IsNullOrWhiteSpace(value))
                return;
            string[] xmlArr = value.Split(';');
            this.c = new Point(Convert.ToInt32(xmlArr[0]), Convert.ToInt32(xmlArr[1]));
        }
    }

    [XmlIgnore]
    public Pen pen { get; set; }
    [XmlElement("PenColor")]
    public int penColor
    {
        get { return pen.Color.ToArgb(); }
        set { this.pen.Color = Color.FromArgb(value); }
    }

    [XmlElement("PenWidth")]
    public float penWidth
    {
        get { return this.pen.Width; }
        set { this.pen.Width = value; }
    }

    [XmlIgnore]
    public SolidBrush brush { get; set; }
    [XmlElement("BrushColor")]
    public int brushColor
    { 
        get { return this.brush.Color.ToArgb();}
        set { this.brush.Color = Color.FromArgb(value); }
    }
    public Triangle()
    {
        a = new Point(0, 0);
        b = new Point(0, 0);
        c = new Point(0, 0);
        pen = new Pen(Color.Black, 1);
    }

    public Triangle(Point a1, Point b1, Point c1, Pen myPen)
    {
        this.a = a1;
        this.b = b1;
        this.c = c1;
        this.pen = myPen;
    }
}

我将我的数字序列化为 xml-结构并保存它们。如果需要,我将它们反序列化并重新绘制在 pictureBox 中。 问题是:当我反序列化 xml 中的图形时,所有填充的图形都具有最后一个图形的颜色。

这是反序列化的一部分:

foreach (XmlNode singleNode in nodes)
{
    Type TestType = GetTypeFromAssemblyByName(singleNode.Attributes.GetNamedItem("d1p1:type").Value);
    if (TestType != null)
    {
        ConstructorInfo ci = TestType.GetConstructor(new Type[] { });
        object Obj = ci.Invoke(new object[] { });
        MethodInfo method = TestType.GetMethod("Deserialize");
        object result = method.Invoke(Obj, new object[] { singleNode.OuterXml });                      
        listObjects.Add(result);
    }
    else
    {
        Console.WriteLine("Class wasn't found");
    }
}

例如我有 2 个填充三角形,它们保存到 Xml。第一个是蓝色,第二个是红色,两者的笔刷颜色不同,这是fillPolygon方法所需要的。

<Workspace>
  <Figure d1p1:type="Figure.FilledTriangle" xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance">
    <a>64;68</a>
    <b>96;295</b>
    <c>283;41</c>
    <PenColor>-16777216</PenColor>
    <PenWidth>1</PenWidth>
    <BrushColor>-16744193</BrushColor>
  </Figure>
  <Figure d1p1:type="Figure.FilledTriangle" xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance">
    <a>321;411</a>
    <b>575;152</b>
    <c>629;462</c>
    <PenColor>-16777216</PenColor>
    <PenWidth>1</PenWidth>
    <BrushColor>-65408</BrushColor>
  </Figure>
</Workspace>

一切似乎都是正确的,但是当我调用反序列化方法时,结果是,列表中所有先前添加的图形的画笔颜色都被重写了。所以在我的示例中,我在他们的正确位置上有两个红色三角形。

我知道列表包含对结果的引用,但其他参数:坐标、笔颜色等保持原样。

我怎样才能摆脱这个?我尝试将结果值写入数组,但即使在数组中它们也被替换了。

更新 1 我使用的反序列化方法:

public class Serializer<T> where T : class
{
    public T Deserialize(string inputXml)
    {
        try
        {
            using (TextReader reader = new StringReader(inputXml))
            {
                var xs = new XmlSerializer(typeof(T));
                return (T)xs.Deserialize(reader);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("An error was caught during deserialization " + ex.Message);
        }
        return null;
    }

可能您将同一支笔分配给不同的数字。如果你改变一个图形中一支笔的颜色,这会改变所有这些图形的颜色。与其改变笔的颜色,不如创建一支新笔。线宽也是如此:

[XmlIgnore]
public Pen pen { get; set; }
[XmlElement("PenColor")]
public int penColor
{
    get { return pen.Color.ToArgb(); }
    set { pen = new Pen(Color.FromArgb(value), pen.Width); }
}

[XmlElement("PenWidth")]
public float penWidth
{
    get { return pen.Width; }
    set { pen = new Pen(pen.Color, value); }
}

画笔也一样。


或者,正如 Hans Passant 所建议的那样,根据需要创建笔和画笔并仅存储它们的属性。

[XmlElement("PenColor")]
public int penColor { get; set; }

[XmlElement("PenWidth")]
public float penWidth  { get; set; }

public Pen CreatePen()
{
    return new Pen(Color.FromArgb(penColor), penWidth);
}

用法:

using (Pen pen = figure.CreatePen()){
    graphics.DrawLine(pen, 0, 0, 10, 50);
    ...
}

声明方法名称中包含 "Create" 而不是 属性 的方法,清楚地表明每次调用都会创建一个新笔,并且笔应在使用后处理, using 语句也是如此。

请注意,笔和刷子不是线程安全的。如果您想通过在不同线程中在后台渲染位图来加快速度,则必须在使用它们时在同一线程中创建这些对象。在另一个线程中进行的更改将导致异常,否则。