aaubry / YamlDotNet

YamlDotNet is a .NET library for YAML
MIT License
2.58k stars 483 forks source link

Support IReadOnlyCollection #1008

Open BenjaminBrienen opened 5 days ago

BenjaminBrienen commented 5 days ago
YamlDotNet.Core.YamlException: No node deserializer was able to deserialize the node into type System.Collections.Generic.IReadOnlyCollection

Properties should not return arraysCA1819

The recommended solution is IReadOnlyCollection, especially if the intent is to have an immutable record.

EdwardCooke commented 4 days ago

Can you share some example code and yaml that you’re trying to deserialize? I think, may be wrong, but we may already support read only collections. Can’t entirely remember

BenjaminBrienen commented 4 days ago
public record Extends(string Template, object Parameters)
{
    public Extends() : this(default!, default!) { }
}
public record Parameter(string Name, string DisplayName, string Type, string Default)
{
    public Parameter() : this(default!, default!, default!, default!) { }
}

#pragma warning disable CA1724 // "Resources" is correct
public record Resources(RepositoryItem[] Repositories)
{
    public Resources() : this([]) { }
}
#pragma warning restore CA1724

public record RepositoryItem(string Repository, string Type, string Name, string Ref)
{
    public RepositoryItem() : this(default!, default!, default!, default!) { }
}

public record Trigger(bool Batch, Branches Branches)
{
    public Trigger() : this(default!, default!) { }
}

public record Branches(string[] Include)
{
    public Branches() : this([]) { }
}

public record Pipeline(Trigger Trigger, Resources Resources, Parameter[] Parameters, Extends Extends)
{
    public Pipeline() : this(default!, default!, default!, default!) { }

    public static Pipeline Parse(string yaml)
    {
        var deserializer = new DeserializerBuilder()
            .WithNamingConvention(CamelCaseNamingConvention.Instance)
            .IgnoreUnmatchedProperties()
            .Build();
        return deserializer.Deserialize<Pipeline>(yaml);
    }
}

You can see here that I had to replace IReadOnlyCollections with arrays and add default constructors. Otherwise, you get the error in the OP. The default constructors can be a seperate issue.