Skip to content
This repository was archived by the owner on Jul 11, 2025. It is now read-only.
This repository was archived by the owner on Jul 11, 2025. It is now read-only.

Make serializer work nicely with autoproperties #864

@Rick-van-Dam

Description

@Rick-van-Dam

Summary

Currently we try to avoid using auto properties because when serializing a instance the serializer will use the name of the backing fields which have a ugly name like <Foo>k__BackingField.

Consider changing the serializers to understand the relationship between the backing fields and the properties to allow them to handle these in a nicer way

Analysis

  • Allows the use of auto properties without downsides in both our code and end users code. Which can clean up some files alot.
  • 3th party types that use autoproperties will end up with the ugly backingfield name in serialized form.
  • In the future features like records might be added to C# which might also make use of properties?
  • We have to find a reliable way to find the relationship between backingfields and properties.

Simple example of getting the backingfield or the autoproperty. No idea if this is stable enough, needs more research.

        const string prefix = "<";
        const string suffix = ">k__BackingField";

        public static FieldInfo GetBackingField(PropertyInfo propertyInfo)
        {
            var backingFieldName = $"{prefix}{propertyInfo.Name}{suffix}";
            return propertyInfo.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).FirstOrDefault(x => x.Name == backingFieldName && x.IsDefined(typeof(CompilerGeneratedAttribute)));
        }

        public static PropertyInfo GetAutoProperty(FieldInfo field)
        {
            if (field.Name.StartsWith(prefix) && field.Name.EndsWith(suffix) && field.IsDefined(typeof(CompilerGeneratedAttribute), true))
            {
                var propertyName = field.Name[prefix.Length..^suffix.Length];
                if (propertyName != null)
                {
                    return field.DeclaringType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
                             .Where(x => x.SetMethod != null && x.SetMethod.IsDefined(typeof(CompilerGeneratedAttribute)))
                             .Where(x => x.GetMethod != null && x.GetMethod.IsDefined(typeof(CompilerGeneratedAttribute)))
                             .FirstOrDefault(x => x.Name == propertyName);
                }
            }
            return null;
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    CleanupImproving form, keeping functionDiscussionNothing to be done until decided otherwiseNice2HaveBeneficial, but only very slightly so

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions