YamlDotNet icon indicating copy to clipboard operation
YamlDotNet copied to clipboard

Duplicate contents represented by Anchor are actually the same reference object

Open Polar-Pumpkin opened this issue 8 months ago • 0 comments
trafficstars

Describe the bug I tried to use anchor to simplify the repetitive content in my yaml configuration. I thought anchor just represented repeated yaml text content, but I found that the objects represented by anchor all refer to the same object, rather than repeatedly creating different (reference) objects as I imagined.

If the deserialized data is read-only, there should be no problem, but occasionally I want to store some states in the deserialized object. At this time, some conflicts will occur due to they are actually the same reference object.

I want to know if this behavior is designed? Is my understanding of anchor wrong? Thank you very much for your answer and help. ❤

To Reproduce

using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace YamlAnchorTest;

public class Configuration {
    public List<Executor> Executors { get; set; }
}

public class Executor {
    public string Name { get; set; }
    public List<Filter> Filters { get; set; }
}

public class Filter {
    public string Type { get; set; }
    public int Value { get; set; }
}

internal static class Program {
    private static void Main(string[] args) {
        var document =
            """
            executors:
              - name: a
                filters: &shared
                  - type: foo
                    value: 1
                  - type: bar
                    value: 2
              - name: b
                filters: *shared
            """;
        var deserializer = new DeserializerBuilder()
            .WithNamingConvention(HyphenatedNamingConvention.Instance)
            .WithEnumNamingConvention(HyphenatedNamingConvention.Instance)
            .Build();
        var conf = deserializer.Deserialize<Configuration>(document);
        Console.WriteLine(ReferenceEquals(conf.Executors[0].Filters, conf.Executors[1].Filters));
        // Output: true
        // If I add an item to the Filters of one Executor at this time, the other Executor will also changed
    }
}

Polar-Pumpkin avatar Feb 27 '25 15:02 Polar-Pumpkin