Reputation: 803
I am trying to serialize a subclass with no parameterless constructor of another serializable class. Regardless of my attempts I always get InvalidOperationException because of no parameterless constructor.
I tried to cast my subclass to base class with both: simlpe casting (by simple casting I mean brackets with desired type in between), and with Convert.ChangeType(...). While former does not work (I still get the exception), the latter method is resulting with InvalidCastException (message says that object must implement IConvertible interface).
Here is base class that is perfectly serializable:
[XmlRoot("NdSRD_Environment")]
public class Environment
{
#pragma warning disable IDE1006 // Naming Styles
[XmlAttribute]
public string id { get; set; }
[XmlElement]
public double realWidth { get; set; }
[XmlElement]
public double realHeight { get; set; }
[XmlElement]
public double realDepth { get; set; }
[XmlElement]
public int PIXEL_WIDTH { get; set; }
[XmlElement]
public int PIXEL_HEIGHT { get; set; }
[XmlElement]
public int PIXEL_DEPTH { get; set; }
[XmlArrayItem(ElementName ="Height")]
[XmlArray]
public List<short> heights { get; set; }
[XmlElement]
public int worldWidthSegments { get; set; }
[XmlElement]
public int worldDepthSegments { get; set; }
#pragma warning restore IDE1006 // Naming Styles
}
And here is the subclass which produces the error:
public class FlatEnvironment : NdSRD.WebService.Core.DataModel.Environment
{
public readonly static int PIXEL_PER_REAL_METER_RATIO = 100;
public FlatEnvironment(double realWidth, double realDepth, double maxHeight)
{
this.PIXEL_WIDTH = (int)realWidth * PIXEL_PER_REAL_METER_RATIO;
this.PIXEL_DEPTH = (int)realDepth * PIXEL_PER_REAL_METER_RATIO;
this.PIXEL_HEIGHT = (int)maxHeight * PIXEL_PER_REAL_METER_RATIO;
this.worldWidthSegments = 128;
this.worldDepthSegments = 128;
this.id = "FLAT_ENVIRONMENT-WxDxmH:" + realWidth + "x" + realDepth + "x" + maxHeight + "-PWxPDxPH:" + PIXEL_WIDTH + "x" + PIXEL_DEPTH + "x" + PIXEL_HEIGHT + " WSxDS:" + this.worldWidthSegments + "x" + this.worldDepthSegments;
this.realWidth = realWidth;
this.realDepth = realDepth;
this.realHeight = maxHeight;
this.heights = new System.Collections.Generic.List<short>();
for (int i = 0; i < (this.worldDepthSegments + 1) * (this.worldWidthSegments + 1); i++)
{
heights.Add(0);
}
}
}
Update 1: Here is my way of serializing mentioned classes:
public void Serialize(string fileName, NdSRD.WebService.Core.DataModel.Environment environment)
{
XmlSerializer xs = new XmlSerializer(typeof(NdSRD.WebService.Core.DataModel.Environment));
System.IO.TextWriter writer = new StreamWriter(fileName);
xs.Serialize(writer, environment);
writer.Close();
}
Upvotes: 1
Views: 102
Reputation: 101662
Is there actually a compelling reason for FlatEnvironment
to be a subclass? It seems that it's not really serving any purpose other than producing an instance of the base class with certain values, in which case, you're probably better off just having a method that does that. This would solve your serialization problems:
// put this in the Environment class or a static class:
public const int PIXEL_PER_REAL_METER_RATIO = 100;
public static Environment FlatEnvironment(double realWidth, double realDepth, double maxHeight)
{
const int worldWidthSegments = 128;
const int worldDepthSegments = 128;
var heights = new System.Collections.Generic.List<short>();
for (int i = 0; i < (worldDepthSegments + 1) * (worldWidthSegments + 1); i++)
{
heights.Add(0);
}
return new Environment {
PIXEL_WIDTH = (int)realWidth * PIXEL_PER_REAL_METER_RATIO,
PIXEL_DEPTH = (int)realDepth * PIXEL_PER_REAL_METER_RATIO,
PIXEL_HEIGHT = (int)maxHeight * PIXEL_PER_REAL_METER_RATIO,
worldWidthSegments = worldWidthSegments,
worldDepthSegments = worldDepthSegments,
id = "FLAT_ENVIRONMENT-WxDxmH:" + realWidth + "x" + realDepth + "x" + maxHeight + "-PWxPDxPH:" + PIXEL_WIDTH + "x" + PIXEL_DEPTH + "x" + PIXEL_HEIGHT + " WSxDS:" + worldWidthSegments + "x" + worldDepthSegments,
realWidth = realWidth,
realDepth = realDepth,
realHeight = maxHeight,
};
}
Upvotes: 3