UnitsNet icon indicating copy to clipboard operation
UnitsNet copied to clipboard

Question about deserializing Lengthns were the XML only has a double value for the length

Open flycast opened this issue 1 year ago • 1 comments

I have XML that looks like this:

<Line>
	<Name>Line1</Name>
	<Volume>235.84905660377359</Volume>
	<StartPoint>
		<X>0.11207695625525477</X>
		<Y>0.13272960272211731</Y>
		<Z>0</Z>
	</StartPoint>
	<EndPoint>
		<X>0.15749675983630079</X>
		<Y>0.30305386615104046</Y>
		<Z>0</Z>
	</EndPoint>
</Line>

I need to deserialize this to custom classes called Line and Point. The X, Y and Z of point or of the type Length. The data deserializes just fine except for the 'Length" types. Those end up with a value of zero. Is there a way to use the XML data above an deserialize to a default LengthUnit type like meter?

Line:

public class Line : IEntity, IDebugOutputable, ISplitable, ILength, IRobotElement
    {
        public string Name { get; set; }

        public Point StartPoint { get; set; } = new(new Length(), new Length(), new Length());
        public Point EndPoint { get; set; } = new(new Length(), new Length(), new Length());
        public double Volume { get; set; } = 0;

        public Length Length
        {
            get
            {
                LengthUnit unit = Length.Info.UnitType;
                double a = Math.Pow(EndPoint.X.Value - StartPoint.X.Value, 2);
                double b = Math.Pow(EndPoint.Y.Value - StartPoint.Y.Value, 2);
                double c = Math.Pow(EndPoint.Z.Value - StartPoint.Z.Value, 2);
                var result =  Length.From( Math.Sqrt(a + b + c), unit) ;
                return result;
            }
        }

        public string DebugOutput()
        {
            StringBuilder result = new();
            result.AppendLine();
            result.AppendLine(Name);
            result.AppendLine($"Start point: {StartPoint.DebugOutput()}");
            result.AppendLine($"End point: {EndPoint.DebugOutput()}");
            result.AppendLine($"Volume: {Math.Round(Volume, 3)}");
            return result.ToString();
        }

        public IEntity Split(double percent)
        {
            if (percent <= 0 || percent >= 1) throw new ArgumentOutOfRangeException("percent must be between 0 and 1");

            Line secondLine = new()
            {
                //Fix start point
                StartPoint = Utils.InterpolatePoint(StartPoint, EndPoint, percent),
                EndPoint = EndPoint,
                Volume = Volume * (1 - percent),
                Name = Name + $" - Remainder"
            };

            //Fix first line
            EndPoint = secondLine.StartPoint;
            Volume *= percent;
            Name += $" - Base";

            return secondLine;
        }
    }

Point:

public class Point : IDebugOutputable
    {
        //public Point() { }

        public Point(Length x, Length y, Length z)
        {
            X = x;
            Y = y;
            Z = z;
        }



        public Length X { get; set; }

        public Length Y { get; set; }

        public Length Z { get; set; }

        public string DebugOutput()
        {
            string result = "";
            result += $"X: {Math.Round(X.Value, 3)}, ";
            result += $"Y: {Math.Round(Y.Value, 3)}, ";
            result += $"Z: {Math.Round(Z.Value, 3)}";
            return result;
        }


    }

flycast avatar May 04 '23 22:05 flycast

You are probably better off having a non-UnitsNet type for serializing/deserializing, then mapping to UnitsNet after deserializing.

Most serializers support some form of plugins to add converters from/to specific types, but the simplest approach is to have separate types for serialization using standard .NET BCL types (double, decimal, string etc), then manually mapping from/to your domain types that use more complex types like UnitsNet quantities.

For example, you can have two classes: SerializablePoint and Point

angularsen avatar May 07 '23 19:05 angularsen

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jul 08 '24 18:07 github-actions[bot]

This issue was automatically closed due to inactivity.

github-actions[bot] avatar Jul 16 '24 02:07 github-actions[bot]