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)
|
private static FastPropertyLookup[] BuildFieldLookup(FieldInfo[] fields)
|
||||||
{
|
{
|
||||||
FastPropertyLookup[] fastLookup = new FastPropertyLookup[fields.Length];
|
FastPropertyLookup[] fastLookup = new FastPropertyLookup[fields.Length];
|
||||||
|
int count = 0;
|
||||||
for (int i = 0; i < fields.Length; ++i)
|
for (int i = 0; i < fields.Length; ++i)
|
||||||
{
|
{
|
||||||
var field = fields[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);
|
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;
|
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)
|
private static FastPropertyLookup[] BuildFastLookup(PropertyInfo[] properties, bool includeType)
|
||||||
{
|
{
|
||||||
int fastAccessIndex = includeType ? 1 : 0;
|
int fastAccessIndex = includeType ? 1 : 0;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace NLog.Targets
|
|||||||
public int MaxRecursionLimit { get; set; } = 10;
|
public int MaxRecursionLimit { get; set; } = 10;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <remarks>Default: <see langword="false"/></remarks>
|
/// <remarks>Default: <see langword="false"/></remarks>
|
||||||
public bool IncludePublicFields { get; set; }
|
public bool IncludePublicFields { get; set; }
|
||||||
|
|||||||
@@ -95,6 +95,16 @@ namespace NLog.UnitTests.Targets
|
|||||||
public string ReadPrivate() => _private;
|
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()
|
private static ContainerClass BuildSampleObject()
|
||||||
{
|
{
|
||||||
var testObject = new ContainerClass
|
var testObject = new ContainerClass
|
||||||
@@ -236,6 +246,12 @@ namespace NLog.UnitTests.Targets
|
|||||||
Assert.Equal(@"{""Name"":""John"",""Age"":42}", withFieldsAgain.ToString());
|
Assert.Equal(@"{""Name"":""John"",""Age"":42}", withFieldsAgain.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IncludePublicFields_ShadowedField_IsWrittenOnce()
|
||||||
|
{
|
||||||
|
Assert.Equal(@"{""Name"":""derived""}", SerializeWithFields(new ClassWithShadowingField()));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void IncludePublicFields_ExpandoObject_StillEnumeratesEntries()
|
public void IncludePublicFields_ExpandoObject_StillEnumeratesEntries()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user