Giter VIP home page Giter VIP logo

Comments (14)

lunarcloud avatar lunarcloud commented on June 9, 2024

it seems to work if there are no objects inside that sub-object without defaults. I'm still not sure the exact scenarios this is and is-not working in

from yamldotnet.

EdwardCooke avatar EdwardCooke commented on June 9, 2024

I haven’t looked to closely at this yet. But. According to this class/code in order to not output PropOfA you would need to set DefaultValue(null) on it.

The way you have your defaultvalue on the integer I would have assumed would work based on the below code. I’ll take a closer look maybe today.

var defaultValue = key.GetCustomAttribute<DefaultValueAttribute>()?.Value ?? GetDefault(key.Type);

from yamldotnet.

EdwardCooke avatar EdwardCooke commented on June 9, 2024

I do feel there is a bug in there since defaults of an instance type is always null. So that should probably be taken into account in that class.

from yamldotnet.

lunarcloud avatar lunarcloud commented on June 9, 2024

I do feel there is a bug in there since defaults of an instance type is always null. So that should probably be taken into account in that class.

So there's no way to omit a non-null default for a YAML sub-category or Array?

from yamldotnet.

EdwardCooke avatar EdwardCooke commented on June 9, 2024

On an instance type you would need to add the defaultvalue of null attribute like you have commented out. I think. I haven’t tested or played with that. I was hoping to have time over the weekend but that didn’t happen.

from yamldotnet.

EdwardCooke avatar EdwardCooke commented on June 9, 2024

Arrays are insurance type. So defaults of that would be null. But you couldn’t do an empty array as a default. If that makes sense.

from yamldotnet.

lunarcloud avatar lunarcloud commented on June 9, 2024

Right, so you're confirming that only primitives can have non-null defaults ( and there's no way to say "this is a static-readonly value I consider default for you to omit").

Okay. That's dissapointing.
Default-omission is the only real way of writing configs that are safe from needing config versioning and a migrator tool between major software releases.

from yamldotnet.

EdwardCooke avatar EdwardCooke commented on June 9, 2024

Ok. Got to spend about 5 minutes. You might. And I strongly emphasize might. Be able to create a custom System.ComponentModel.TypeDescriptionProvider. Register it with System.ComponentModel.TypeConverter.AddProvider.

Then when you specify the DefaultValue attribute put the type and probably and empty string.

You will also need to create an Equals override method on your class. Then you could do all sorts of things. No guarantees that it will work though.

from yamldotnet.

edwardcookemacu avatar edwardcookemacu commented on June 9, 2024

Figured it out for you using TypeConverters and no changes necessary to the YamlDotNet code base. The following code will exclude the PropOfA attribute from the yaml if PropOfB is 3. This results in the output of {} (an empty Yaml). Is that what you are looking for?

var instanceOfA = new ExampleA(); // leaving the defaults
var text = new SerializerBuilder()
        .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults)
        .Build()
        .Serialize(instanceOfA);
Console.WriteLine(text);
Console.ReadLine();

public class ExampleBTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
    {
        if (string.IsNullOrEmpty(value as string))
        {
            // Default value to check against
            return new ExampleB { PropOfB = 3 };
        }

        return null;
    }
}

[TypeConverter(typeof(ExampleBTypeConverter))]
public class ExampleB
{
    public ExampleB() { }

    public int PropOfB { get; set; } = 3;

    public override bool Equals(object? obj)
    {
        return (obj as ExampleB)?.PropOfB == PropOfB;
    }
}

public class ExampleA
{
    public ExampleA() { }

    [DefaultValue(typeof(ExampleB), null)]
    public ExampleB PropOfA { get; set; } = new();
}

from yamldotnet.

edwardcookemacu avatar edwardcookemacu commented on June 9, 2024

If you want to exclude PropOfB from the output, where PropOfA is still there, then this works by outputting PropOfA: {}:

var instanceOfA = new ExampleA(); // leaving the defaults
var text = new SerializerBuilder()
        .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults)
        .Build()
        .Serialize(instanceOfA);
Console.WriteLine(text);
Console.ReadLine();


public class ExampleB
{
    public ExampleB() { }

    [DefaultValue(3)]
    public int PropOfB { get; set; } = 3;

    public override bool Equals(object? obj)
    {
        return (obj as ExampleB)?.PropOfB == PropOfB;
    }
}

public class ExampleA
{
    public ExampleA() { }

    public ExampleB PropOfA { get; set; } = new();
}

from yamldotnet.

lunarcloud avatar lunarcloud commented on June 9, 2024

It doesn't solve my issues with arrays, but it absolutely fixes the bug report as it's written.

from yamldotnet.

edwardcookemacu avatar edwardcookemacu commented on June 9, 2024

If you don't have to have it as an array, you could create another class inheriting List<ExampleB>. There's also another option if you do have to have it exposed as an array, use [YamlMember] and [YamlIgnore] and have one property be this subclassed list, and another being the array.

Like this:

var instanceOfA = new ExampleA
{
    PropOfA = new ExampleBList
    {
        new ExampleB
        {
            PropOfB = 3
        }
    }
};

var text = new SerializerBuilder()
        .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults)
        .Build()
        .Serialize(instanceOfA);
Console.WriteLine(text);
Console.ReadLine();

public class ExampleB
{
    public ExampleB() { }

    public int PropOfB { get; set; }

    public override bool Equals(object? obj)
    {
        return (obj as ExampleB)?.PropOfB == PropOfB;
    }
}

public class ExampleA
{
    public ExampleA() { }

    [DefaultValue(typeof(ExampleBList), null)]
    public ExampleBList PropOfA { get; set; }
}

public class ExampleBListTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
    {
        if (string.IsNullOrEmpty(value as string))
        {
            return new ExampleBList
            {
                new ExampleB()
                {
                     PropOfB = 3
                }
            };
        }

        return null;
    }
}

[TypeConverter(typeof(ExampleBListTypeConverter))]
public class ExampleBList : List<ExampleB>
{
    public override bool Equals(object? obj)
    {
        var list = obj as IEnumerable<ExampleB>;

        if (list != null)
        {
            if (this.Count == list.Count())
            {
                foreach (var item in this)
                {
                    //make sure each item in the incoming list only exists once in this list
                    if (list.Where(x => x.Equals(item)).Count() != 1)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }
}

from yamldotnet.

edwardcookemacu avatar edwardcookemacu commented on June 9, 2024

If you need to have it exposed as an array, you can do something like this with the YamlMember and YamlIgnore attributes.

var instanceOfA = new ExampleA
{
    PropOfA = new []
    {
        new ExampleB
        {
            PropOfB = 3
        }
    }
};

var text = new SerializerBuilder()
        .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitDefaults)
        .Build()
        .Serialize(instanceOfA);
Console.WriteLine(text);
Console.ReadLine();

public class ExampleB
{
    public ExampleB() { }

    public int PropOfB { get; set; }

    public override bool Equals(object? obj)
    {
        return (obj as ExampleB)?.PropOfB == PropOfB;
    }
}

public class ExampleA
{
    public ExampleA() { }

    [DefaultValue(typeof(ExampleBList), null)]
    [YamlMember(Alias = "PropOfA")]
    public ExampleBList PropOfADefaulted { get; set; }

    [YamlIgnore]
    public ExampleB[] PropOfA
    {
        get
        {
            return PropOfADefaulted.ToArray();
        }
        set
        {
            PropOfADefaulted = new ExampleBList(value);
        }
    }
}

public class ExampleBListTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
    {
        if (string.IsNullOrEmpty(value as string))
        {
            return new ExampleBList
            {
                new ExampleB()
                {
                     PropOfB = 3
                }
            };
        }

        return null;
    }
}

[TypeConverter(typeof(ExampleBListTypeConverter))]
public class ExampleBList : List<ExampleB>
{
    public ExampleBList() { }
    public ExampleBList(IEnumerable<ExampleB> collection) : base(collection) { }

    public override bool Equals(object? obj)
    {
        var list = obj as IEnumerable<ExampleB>;

        if (list != null)
        {
            if (this.Count == list.Count())
            {
                foreach (var item in this)
                {
                    //make sure each item in the incoming list only exists once in this list
                    if (list.Where(x => x.Equals(item)).Count() != 1)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }
}

from yamldotnet.

lunarcloud avatar lunarcloud commented on June 9, 2024

Thank you very much. No my secondary problem was with having a default value for a primitive array like int[] but this is very very helpful info.

from yamldotnet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.