Skip to content

Commit a374d52

Browse files
committed
As reported in Issue #216, when using a calculated binding,
with a ValueGetter, the getter appears to be evaluted only once when initially converted to a TypeNode. This is unfortunately prior to any deserialized values being realised. This is a slightly hacky solution, but simply re-attempts to evaluate getters where this is the case. Signed-off-by: Bevan Weiss <[email protected]>
1 parent 732c2c4 commit a374d52

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
3+
namespace BinarySerialization.Test.Issues.Issue216
4+
{
5+
[TestClass]
6+
public class Issue216Tests : TestBase
7+
{
8+
[TestMethod]
9+
public void TestIssue216()
10+
{
11+
var expected = new Preview
12+
{
13+
ResolutionX = 2,
14+
ResolutionY = 3,
15+
Data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
16+
Empty = 0,
17+
};
18+
19+
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 });
20+
Assert.AreEqual(expected.ResolutionX, actual.ResolutionX);
21+
Assert.AreEqual(expected.ResolutionY, actual.ResolutionY);
22+
Assert.AreEqual(expected.Data.Length, actual.Data.Length);
23+
for (int i = 0; i < expected.Data.Length; i++)
24+
Assert.AreEqual(expected.Data[i], actual.Data[i]);
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace BinarySerialization.Test.Issues.Issue216
2+
{
3+
public class Preview
4+
{
5+
/// <summary>
6+
/// Gets the image width, in pixels.
7+
/// </summary>
8+
[FieldOrder(0)]
9+
public uint ResolutionX { get; set; }
10+
11+
/// <summary>
12+
/// Gets the image height, in pixels.
13+
/// </summary>
14+
[FieldOrder(2)]
15+
public uint ResolutionY { get; set; }
16+
17+
[Ignore]
18+
public uint DataSize => ResolutionX * ResolutionY * 2;
19+
20+
[FieldOrder(3)]
21+
[FieldCount(nameof(DataSize), BindingMode = BindingMode.OneWay)]
22+
public byte[] Data { get; set; }
23+
24+
[FieldOrder(4)]
25+
public uint Empty;
26+
}
27+
}

BinarySerializer/Graph/Binding.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ public object GetValue(ValueNode target)
7777

7878
CheckSource(source);
7979

80+
// When using a calculated Ignore field, the evaluation of the value is not
81+
// deferred until required non-Ignore fields are calculated.
82+
// This is a hack, but if the value is null, we will re-evaluate the getter
83+
if (source.Value == null && source.TypeNode.ValueGetter != null)
84+
source.Value = source.TypeNode.ValueGetter.Invoke(source.Parent.Value);
85+
8086
return ValueConverter == null
8187
? source.Value
8288
: Convert(source.Value, target.CreateLazySerializationContext());

0 commit comments

Comments
 (0)