public void DumpProperty() { // should we dump it at all? if (!CurrentMember.CanRead() || CurrentMemberDumpAttribute.Skip == ShouldDump.Skip) { return; } var pi = CurrentMember as PropertyInfo; // can't dump indexers if (pi != null && pi.GetIndexParameters().Length > 0) { return; } if (pi != null && pi.IsVirtual()) { // for virtual properties dump the instance value at the the least derived class level that declares the property for first time. if (CurrentType.BaseType.GetProperty(CurrentMember.Name, _dumper.Settings.PropertyBindingFlags) != null) { return; } pi = InstanceType.GetProperty(CurrentMember.Name, _dumper.Settings.PropertyBindingFlags); } var fi = CurrentMember as FieldInfo; Type type = null; object value = null; try { if (pi != null) { type = pi.PropertyType; value = pi.GetValue(Instance, null); } else { type = fi.FieldType; value = fi.GetValue(Instance); } } catch (Exception x) { // this should not happen but... value = $"<{x.Message}>"; } var dontDumpNulls = CurrentMemberDumpAttribute.DumpNullValues == ShouldDump.Skip || CurrentMemberDumpAttribute.DumpNullValues == ShouldDump.Default && DumpNullValues == ShouldDump.Skip; if (IsInDumpingMode) { // should we dump a null value of the current property if (value == null && dontDumpNulls) { return; } // write the property header _dumper.Writer.WriteLine(); _dumper.Writer.Write( CurrentMemberDumpAttribute.LabelFormat, CurrentMember.Name); if (!(DumpedPropertyCustom(value, type) || // dump the property value using caller's customization (see ValueFormat="ToString", DumpClass, DumpMethod) if any. _dumper.Writer.DumpedBasicValue(value, CurrentMemberDumpAttribute) || _dumper.Writer.DumpedBasicNullable(value, CurrentMemberDumpAttribute) || _dumper.Writer.Dumped(value as Delegate) || _dumper.Writer.Dumped(value as MemberInfo) || DumpedCollection(value, CurrentMember, CurrentMemberDumpAttribute))) { // dump a property representing an associated class or struct object var currentPropertyDumpAttribute = !CurrentMemberDumpAttribute.IsDefaultAttribute() ? CurrentMemberDumpAttribute : null; _dumper.DumpObject(value, null, currentPropertyDumpAttribute, this); } } else { // write the property header DumpScript.BeginDumpProperty(CurrentMember, CurrentMemberDumpAttribute); if (!DumpedPropertyCustom(value, type)) // dump the property value using caller's customization (see ValueFormat="ToString", DumpClass, DumpMethod) if any. { DumpScript.AddDumpPropertyOrCollectionValue(CurrentMember, CurrentMemberDumpAttribute); } DumpScript.EndDumpProperty(CurrentMember, dontDumpNulls); } }