Describe IncludePublicFields as a fallback and write a shadowed field once
This commit is contained in:
1 parent
f078e2a2c0
commit
05f5fc4dc9
3 files changed
+35
-2
No files matched your search
@@ -298,15 +298,32 @@ namespace NLog.Internal
|
||||
private static FastPropertyLookup[] BuildFieldLookup(FieldInfo[] fields)
|
||||
{
|
||||
FastPropertyLookup[] fastLookup = new FastPropertyLookup[fields.Length];
|
||||
int count = 0;
|
||||
for (int i = 0; i < fields.Length; ++i)
|
||||
{
|
||||
var field = fields[i];
|
||||
if (IsHiddenByDerivedField(field, fields))
|
||||
continue; // A derived type redeclared the name with "new", so the member is written once
|
||||
|
||||
TypeCode typeCode = Type.GetTypeCode(field.FieldType);
|
||||
fastLookup[i] = new FastPropertyLookup(field.Name, typeCode, (o, p) => field.GetValue(o));
|
||||
fastLookup[count++] = new FastPropertyLookup(field.Name, typeCode, (o, p) => field.GetValue(o));
|
||||
}
|
||||
|
||||
if (count != fastLookup.Length)
|
||||
Array.Resize(ref fastLookup, count);
|
||||
return fastLookup;
|
||||
}
|
||||
|
||||
private static bool IsHiddenByDerivedField(FieldInfo field, FieldInfo[] fields)
|
||||
{
|
||||
foreach (var other in fields)
|
||||
{
|
||||
if (!ReferenceEquals(other, field) && other.Name == field.Name && other.DeclaringType != null && field.DeclaringType != null && other.DeclaringType.IsSubclassOf(field.DeclaringType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static FastPropertyLookup[] BuildFastLookup(PropertyInfo[] properties, bool includeType)
|
||||
{
|
||||
int fastAccessIndex = includeType ? 1 : 0;
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace NLog.Targets
|
||||
public int MaxRecursionLimit { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Should public fields be included in the JSON output, in addition to public properties.
|
||||
/// Should public fields be included in the JSON output, for objects that have no public properties.
|
||||
/// </summary>
|
||||
/// <remarks>Default: <see langword="false"/></remarks>
|
||||
public bool IncludePublicFields { get; set; }
|
||||
|
||||
@@ -95,6 +95,16 @@ namespace NLog.UnitTests.Targets
|
||||
public string ReadPrivate() => _private;
|
||||
}
|
||||
|
||||
private class ClassWithBaseField
|
||||
{
|
||||
public string Name = "base";
|
||||
}
|
||||
|
||||
private sealed class ClassWithShadowingField : ClassWithBaseField
|
||||
{
|
||||
public new string Name = "derived";
|
||||
}
|
||||
|
||||
private static ContainerClass BuildSampleObject()
|
||||
{
|
||||
var testObject = new ContainerClass
|
||||
@@ -236,6 +246,12 @@ namespace NLog.UnitTests.Targets
|
||||
Assert.Equal(@"{""Name"":""John"",""Age"":42}", withFieldsAgain.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IncludePublicFields_ShadowedField_IsWrittenOnce()
|
||||
{
|
||||
Assert.Equal(@"{""Name"":""derived""}", SerializeWithFields(new ClassWithShadowingField()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IncludePublicFields_ExpandoObject_StillEnumeratesEntries()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user