Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement]Improved way to exclude (readonly) properties #112

Open
ibs-ts opened this issue Jul 7, 2023 · 0 comments
Open

[Enhancement]Improved way to exclude (readonly) properties #112

ibs-ts opened this issue Jul 7, 2023 · 0 comments

Comments

@ibs-ts
Copy link

ibs-ts commented Jul 7, 2023

Summary

Currently the only way to exclude (readonly) properties is by using DumpOptions.ExcludeProperties.
It excludes all properties matching the names in the to-dump-object(-tree).
There might be use cases, where this is not preferred.

Intended Use Case

Let say, you want to dump an object with a readonly property, my current approach to produce compilable output would be by using 'ExcludeProperties'

var point = new System.Drawing.Point() { X = 1, Y = 0 };

var str = ObjectDumper.Dump(point, new DumpOptions()
{
    IndentChar = '\t',
    IndentSize = 1,
    LineBreakChar = Environment.NewLine,
    DumpStyle = DumpStyle.CSharp,
    ExcludeProperties = new string[]
    {
        nameof(Point.IsEmpty)
    }
});
Console.WriteLine(str);

However, if you've a more complex object (tree), where property names are duplicated, this lead to 'all or nothing':

var expection = new Expection() 
{ 
    Operands = Enumerable.Range(1, 5).ToArray(),
    Result = 15
};
var tester = new Tester(expection);

var str = ObjectDumper.Dump(tester, new DumpOptions()
{
    IndentChar = '\t',
    IndentSize = 1,
    LineBreakChar = Environment.NewLine,
    DumpStyle = DumpStyle.CSharp,
    ExcludeProperties = new string[]
    {
        //"Result"
    }
});

Console.WriteLine(str);

public class Tester
{
    public Tester(Expection expection)
    {
        Expection = expection;
        Actual = (Actual)expection;
    }

    public Expection Expection { get; }
    public Actual Actual { get; }
}

public class Expection
{
    public int Result { get; set; }
    public int[] Operands { get; set; }
    public static explicit operator Actual(Expection e) => new() { Operands = e.Operands };
}

public struct Actual
{
    public int Result => Operands.Sum();
    public int[] Operands { get; init; }
}

API Changes

I can think of three solutions for this

full qualified property names of the tree

Add an string interpretation which might point to the exact property
e.g. "Expection.Result" of the to-dump Tester object
Disadvantage: The '.' of object separation is very c#-specific and might lead to confusions

ExcludeReadonlyProperties

Add this to the DumpOptions to auto exclude all properties, which are readonly.
Disadvantage 1: what is readonly? everything which hasn't a public setter? what about objects with protect setter?
Disadvantage 2: You might include some readonly properties in the console-output, but exclude the rest of readonly members - this leads to the initial problem

Provide an interface for excluding

Something like

public interface IPropertyExcluder
{
    public bool ShouldExcludeProperty(in object obj, in string propertyName);
}

And an respective array on DumpOptions

So it could be used depending on the use case:

public class ActualPropertyExcluder : IPropertyExcluder
{
    public bool ShouldExcludeProperty(in object obj, in string propertyName)
        => (obj is Actual) && propertyName == nameof(Actual.Result);
}

ObjectDumper.Dump(tester, new DumpOptions()
{
    IndentChar = '\t',
    IndentSize = 1,
    LineBreakChar = Environment.NewLine,
    DumpStyle = DumpStyle.CSharp,
    ExcludeProperties = new IPropertyExcluder[]
    {
        new ActualPropertyExcluder()
    }
});

Advantage 1: The consumer can decide, which property should be excluded (depending on the use case)
Advantage 2: DumpOptions properties 'SetPropertiesOnly' could also be obsoleted
Disadvantage: Breaking Change when used ExcludeProperties with older versions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant