diff --git a/BinarySerializer.Test/Issues/Issue216/Issue216Test.cs b/BinarySerializer.Test/Issues/Issue216/Issue216Test.cs new file mode 100644 index 00000000..eae0fee4 --- /dev/null +++ b/BinarySerializer.Test/Issues/Issue216/Issue216Test.cs @@ -0,0 +1,27 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BinarySerialization.Test.Issues.Issue216 +{ + [TestClass] + public class Issue216Tests : TestBase + { + [TestMethod] + public void TestIssue216() + { + var expected = new Preview + { + ResolutionX = 2, + ResolutionY = 3, + Data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, + Empty = 0, + }; + + var actual = Roundtrip(expected, new byte[] { 2, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0 }); + Assert.AreEqual(expected.ResolutionX, actual.ResolutionX); + Assert.AreEqual(expected.ResolutionY, actual.ResolutionY); + Assert.AreEqual(expected.Data.Length, actual.Data.Length); + for (int i = 0; i < expected.Data.Length; i++) + Assert.AreEqual(expected.Data[i], actual.Data[i]); + } + } +} diff --git a/BinarySerializer.Test/Issues/Issue216/PreviewClass.cs b/BinarySerializer.Test/Issues/Issue216/PreviewClass.cs new file mode 100644 index 00000000..1eb8ba00 --- /dev/null +++ b/BinarySerializer.Test/Issues/Issue216/PreviewClass.cs @@ -0,0 +1,27 @@ +namespace BinarySerialization.Test.Issues.Issue216 +{ + public class Preview + { + /// + /// Gets the image width, in pixels. + /// + [FieldOrder(0)] + public uint ResolutionX { get; set; } + + /// + /// Gets the image height, in pixels. + /// + [FieldOrder(2)] + public uint ResolutionY { get; set; } + + [Ignore] + public uint DataSize => ResolutionX * ResolutionY * 2; + + [FieldOrder(3)] + [FieldCount(nameof(DataSize), BindingMode = BindingMode.OneWay)] + public byte[] Data { get; set; } + + [FieldOrder(4)] + public uint Empty; + } +} diff --git a/BinarySerializer/Graph/Binding.cs b/BinarySerializer/Graph/Binding.cs index cad186e7..8c696c98 100644 --- a/BinarySerializer/Graph/Binding.cs +++ b/BinarySerializer/Graph/Binding.cs @@ -77,6 +77,12 @@ public object GetValue(ValueNode target) CheckSource(source); + // When using a calculated Ignore field, the evaluation of the value is not + // deferred until required non-Ignore fields are calculated. + // This is a hack, but if the value is null, we will re-evaluate the getter + if (source.Value == null && source.TypeNode.ValueGetter != null) + source.Value = source.TypeNode.ValueGetter.Invoke(source.Parent.Value); + return ValueConverter == null ? source.Value : Convert(source.Value, target.CreateLazySerializationContext());