diff --git a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs index 2e7b3a43f37b..f3cdf58cf092 100644 --- a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs +++ b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs @@ -433,7 +433,9 @@ public void Merge(bool useDynamicMessage) } [Test] - public void MergeWrapperFields() + [TestCase(true)] + [TestCase(false)] + public void MergeWrapperFields(bool replaceFields) { // Instantiate a destination with wrapper-based field types. var destination = new TestWellKnownTypes() @@ -452,7 +454,17 @@ public void MergeWrapperFields() }; Merge(new FieldMaskTree().AddFieldPath("string_field").AddFieldPath("int64_field"), - source, destination, new FieldMask.MergeOptions(), false); + source, + destination, + new FieldMask.MergeOptions() + { + // Prove that setting the replace options has no bearing on the outcome of a merge operation + // for well-known wrapper fields as they are semantically equivalent to primitive value fields. + // For those fields "merge" is the same as "replace". + ReplaceMessageFields = replaceFields, + ReplacePrimitiveFields = replaceFields + }, + false); // Make sure only the targeted fields were updated. Assert.AreEqual("Hi", destination.StringField); diff --git a/csharp/src/Google.Protobuf/FieldMaskTree.cs b/csharp/src/Google.Protobuf/FieldMaskTree.cs index 98f321a17300..f610c2796640 100644 --- a/csharp/src/Google.Protobuf/FieldMaskTree.cs +++ b/csharp/src/Google.Protobuf/FieldMaskTree.cs @@ -316,9 +316,10 @@ public void Merge(IMessage source, IMessage destination, FieldMask.MergeOptions else { var sourceField = field.Accessor.GetValue(source); - if (field.FieldType == FieldType.Message && !field.MessageType.IsWrapperType) + if (field.FieldType == FieldType.Message) { - if (options.ReplaceMessageFields) + // Semantically well-known wrapper types represent primitive values, so we do not "merge" them. + if (options.ReplaceMessageFields || field.MessageType.IsWrapperType) { if (sourceField == null) {