Reputation: 3717
How can I mark properties with an order attribute of some kind to help me iterate through them in order, to read a delimited file.
The classes were created with a property for each column, and I'd like to write a routine to handle it instead of doing it by hand.
Something like:
[Order(1)]
public string Field1 { get; set; }
[Order(2)]
public string Field2 { get; set; }
Then something like:
MemberInfo[] myMembers = myType.GetMembers()
.OrderBy(something here or in a loop);
Any thoughts?
Upvotes: 2
Views: 465
Reputation: 8595
You need an OrderAttribute class:
public class OrderAttribute : Attribute
{
public OrderAttribute(int value)
{
this.Value = value;
}
public int Value { get; private set; }
}
Then, you can order by the property as follows:
MemberInfo[] myMembers = typeof(object).GetMembers()
.OrderBy(m => m.GetCustomAttribute<OrderAttribute>().Value);
This is just a basic example of how to do this, I would recommend checking that your member actually has this attribute, and throwing either an appropriate error if it doesn't, or assuming a default value
Upvotes: 3
Reputation: 129
I would do that like that:
var members = myType.GetMembers()
.Where(m => Attribute.IsDefined(m, typeof(OrderAttribute)))
.OrderBy(m => m.GetCustomAttribute<OrderAttribute>().Order);
I check if OrderAttribute is defined so it wont throw null reference exception.
OrderAttribute.cs
public class OrderAttribute : Attribute
{
public OrderAttribute(int order)
{
Order = order;
}
public int Order { get; private set; }
}
Upvotes: 0
Reputation: 951
What you are proposing is doable.
Create an attribute:
public class OrderAttribute : Attribute
{
public int Order { get; private set; }
public OrderAttribute(int order)
{
Order = order;
}
}
Then in your OrderBy call get the OrderAttribute.Order field via reflection also. It would probably be better to put that logic in its own method or create an extension method on PropertyInfo.
SO it would look like this:
MemberInfo[] myMembers = myType.GetMembers()
.OrderBy(m => m.GetAttribute<OrderAttribute>().Order);
I created a generic extension method to handle attribute retrieval.
public static TAttribute GetAttribute<TAttribute>(this object obj)
where TAttribute : Attribute
{
return obj.GetType().GetAttribute<TAttribute>();
}
public static TAttribute GetAttribute<TAttribute>(this ICustomAttributeProvider propInfo, bool inherit = true)
where TAttribute : Attribute
{
return (TAttribute)propInfo.GetCustomAttributes(typeof(TAttribute), inherit).FirstOrDefault();
}
Upvotes: 3
Reputation: 532445
Use the CustomAttributes property on the MemberInfo
to get the OrderAttribute
and select it's value for the ordering.
var members = myType.GetMembers()
.OrderBy(m => m.CustomAttributes
.OfType(typeof(OrderAttribute))
.FirstOrDefault(a => a.Value))
Upvotes: 2