Get Properties in Order of Declaration Using Reflection

Get properties in order of declaration using reflection

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:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class OrderAttribute : Attribute
{
private readonly int order_;
public OrderAttribute([CallerLineNumber]int order = 0)
{
order_ = order;
}

public int Order { get { return order_; } }
}

public class Test
{
//This sets order_ field to current line number
[Order]
public int Property2 { get; set; }

//This sets order_ field to current line number
[Order]
public int Property1 { get; set; }
}

And then use reflection:

var properties = from property in typeof(Test).GetProperties()
where Attribute.IsDefined(property, typeof(OrderAttribute))
orderby ((OrderAttribute)property
.GetCustomAttributes(typeof(OrderAttribute), false)
.Single()).Order
select property;

foreach (var property in properties)
{
//
}

If you have to deal with partial classes, you can additionaly sort the properties using [CallerFilePath].

Get properties of class by order using reflection

You are missing brackets () on FirstOrDefault operator. Also you should deal with case when default value is returned. I suggest to select Order value before getting first or default value. That will return 0 for all properties which don't have DisplayAttribute:

var prop = typeof(A)
.GetProperties()
.OrderBy(p => p.GetCustomAttributes(typeof(DisplayAttribute), true)
.Cast<DisplayAttribute>()
.Select(a => a.Order)
.FirstOrDefault());

If you want properties without DisplayAttribute to be last, you can provide Int32.MaxValue as default value to be returned:

                   .Select(a => a.Order)
.DefaultIfEmpty(Int32.MaxValue)
.First()

`Type.GetProperties` property order

The order simply isn't guaranteed; whatever happens.... Happens.

Obvious cases where it could change:

  • anything that implements ICustomTypeDescriptor
  • anything with a TypeDescriptionProvider

But a more subtle case: partial classes. If a class is split over multiple files, the order of their usage is not defined at all. See Is the "textual order" across partial classes formally defined?

Of course, it isn't defined even for a single (non-partial) definition ;p

But imagine

File 1

partial class Foo {
public int A {get;set;}
}

File 2

partial class Foo {
public int B {get;set:}
}

There is no formal declaration order here between A and B. See the linked post to see how it tends to happen, though.


Re your edit; the best approach there is to specify the marshal info separately; a common approach would be to use a custom attribute that takes a numeric order, and decorate the members with that. You can then order based on this number. protobuf-net does something very similar, and frankly I'd suggest using an existing serialization library here:

[ProtoMember(n)]
public int Foo {get;set;}

Where "n" is an integer. In the case of protobuf-net specifically, there is also an API to specify these numbers separately, which is useful when the type is not under your direct control.

C# Reflection property order

The fields in a type are not "ordered". The ordering of the items in those methods is an implementation detail and relying on them is strongly discouraged.

You should order the items yourself, with the expectation that they could start at any position, to ensure your program is robust instead of fragile.

Since each property can be asked for the type that declares it you can create a lookup at the start that gives a number to each class in the hierarchy from the type you start with all the way up to object by walking the BaseType property of Type and order by the lookup value of the declaring type of each property:

public static IEnumerable<PropertyInfo> GetOrderedProperties(Type type)
{
Dictionary<Type, int> lookup = new Dictionary<Type, int>();

int count = 0;
lookup[type] = count++;
Type parent = type.BaseType;
while (parent != null)
{
lookup[parent] = count;
count++;
parent = parent.BaseType;
}

return type.GetProperties()
.OrderByDescending(prop => lookup[prop.DeclaringType]);
}

Get attributes in order of declaration using reflection

The C# language specification says in 17.2 Attribute specification:

The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant.

For instance, the attribute specifications [A][B], [B][A], [A, B], and [B, A] are equivalent.

So the compiler can re-order them as it wants, and the methods for retrieving attributes can't guarantee to return them in any order.

You can of course use the workaround proposed in the question you link to, using [CallerLineNumber].

How to get class properties in order of declaration when serialize

Properties are not guaranteed to have or maintain any specific order in JavaScript. What you will do in your C# code can't change this "limitation".

BTW, the same goes for .net.

Get properties from class object using reflection where property should be public and having get or get and set both

You should not be using the bitwise AND (&), but the bitwise OR (|):

var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);

Kotlin get property in the same order they are declared

Easier way would be to read properties from the constructor:

 ClassWithSortedProperties::class.
primaryConstructor?.
parameters?.
forEachIndexed { i, property ->
println("$i $property")
}


Related Topics



Leave a reply



Submit