[Enhancement]Improved way to exclude (readonly) properties
Opened this issue · 0 comments
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