I am implementing a custom IFormatter to serialize objects into a custom format that is required by our legacy systems.
If I declare a C# auto property:
[StringLength(15)]
public MyProperty { get; set; }
And then in my custom serialize method I get the serialized fields via:
MemberInfo[] members =
FormatterServices.GetSerializableMembers(graph.GetType(), Context);
How can I access the StringLength attribute that decorates the auto Property?
I am currently getting the property info by taking advantage of the <PropertyName>k_backingfield naming convention. I’d rather not rely on this as it seems to be a specific detail of the C# compiler implementation. Is there a better way?
The better way would be to stop relying on private fields for serialization (as
FormatterServices.GetSerializableMembersreturns) and only use public Properties instead.It is a LOT cleaner and works in this specific case.
But due to legacy code you might want to continue to use
FormatterServices.GetSerializableMembersand in this case, no there is no other options for you other than using the naming convention (Or a little bit of IL analysis) and it may break at each new compiler release.Just for fun here is some code to do a little bit of IL analysis (It lack ignoring NOOPs and other niceties but should work with most current compilers. If you really adopt such a solution check the Cecil library (written by Jb Evain) as it contains a full decompiler and it’s better than doing it by hand.
It’s usage is like this :
And the code :