I need to get all the properties using reflection in the order in which they are declared in the class. According to MSDN the order can not be guaranteed when using GetProperties()
The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order.
But I've read that there is a workaround by ordering the properties by the MetadataToken
. So my question is, is that safe? I cant seem find any information on MSDN about it. Or is there any other way of solving this problem?
My current implementation looks as follows:
var props = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.OrderBy(x => x.MetadataToken);
I did it this way:
with the property declared as follows:
If you are happy with the extra dependency, Marc Gravell's Protobuf-Net can be used to do this without having to worry about the best way to implement reflection and caching etc. Just decorate your fields using
[ProtoMember]
and then access the fields in numerical order using:According to MSDN
MetadataToken
is unique inside one Module - there is nothing saying that it guarantees any order at all.EVEN if it did behave the way you want it to that would be implementation-specific and could change anytime without notice.
See this old MSDN blog entry.
I would strongly recommend to stay away from any dependency on such implementation details - see this answer from Marc Gravell.
IF you need something at compile time you could take a look at Roslyn (although it is in a very early stage).
What I have tested sorting by MetadataToken works.
Some of users here claims this is somehow not good approach / not reliable, but I haven't yet seen any evidence of that one - perhaps you can post some code snipet here when given approach does not work ?
About backwards compatibility - while you're now working on your .net 4 / .net 4.5 - Microsoft is making .net 5 or higher, so you pretty much can assume that this sorting method won't be broken in future.
Of course maybe by 2017 when you will be upgrading to .net9 you will hit compatibility break, but by that time Microsoft guys will probably figure out the "official sort mechanism". It does not makes sense to go back or break things.
Playing with extra attributes for property ordering also takes time and implementation - why to bother if MetadataToken sorting works ?
On .net 4.5 (and even .net 4.0 in vs2012) you can do much better with reflection using clever trick with
[CallerLineNumber]
attribute, letting compiler insert order into your properties for you:And then use reflection:
If you have to deal with partial classes, you can additionaly sort the properties using
[CallerFilePath]
.You may use DisplayAttribute in System.Component.DataAnnotations, instead of custom attribute. Your requirement has to do something with display anyway.