自定义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 语句也是如此。
请注意,笔和刷子不是线程安全的。如果您想通过在不同线程中在后台渲染位图来加快速度,则必须在使用它们时在同一线程中创建这些对象。在另一个线程中进行的更改将导致异常,否则。
我有一个三角形的自定义 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 语句也是如此。
请注意,笔和刷子不是线程安全的。如果您想通过在不同线程中在后台渲染位图来加快速度,则必须在使用它们时在同一线程中创建这些对象。在另一个线程中进行的更改将导致异常,否则。