I have an interface that defines a method for returning an IList<PropertyInfo> :
public interface IWriteable
{
IList<PropertyInfo> WriteableProperties();
}
.
.
It is implemented in various (dissimilar) classes in the following manner:
public abstract class Foo
{
private IList<PropertyInfo> _props;
protected Foo()
{
this._props = new List<PropertyInfo>();
foreach (PropertyInfo p in this.GetType().GetProperties())
{
if (Attribute.IsDefined(p, typeof(WriteableAttribute)))
this._props.Add(p);
}
}
#region IWriteable Members
public IList<PropertyInfo> WriteableProperties()
{
return this._props;
}
#endregion
}
public class Bar : Foo
{
public string A
{
get { return "A"; }
}
[Writeable()]
public string B
{
get { return "B"; }
}
[Writeable()]
public string C
{
get { return "C"; }
}
// Snip
}
Please note the attributes marking a couple of the properties, as these are the properties that will get added to the list. This IList will then be used elsewhere during some file write operations.
It is important to me that they are ordered in the list in the order they appear in the code file.
However, MSDN states:
The GetProperties method does not return properties in a particular
order, such as alphabetical or declaration order. Your code must not
depend on the order in which properties are returned, because that
order varies.
So, what is the best way to ensure each PropertyInfo gets added in the order I would like to to be?
(I am also using .NET2.0, so I can’t use any Linq goodness, should there be any that would help, although it would be interesting to see.)
Add information to the attribute about the ordering, you can then use this to ensure the ordering, e.g.:
So for the following attribute:
You can get an ordered selection of the properties as follows:
NB For production code I would recommend caching the property information (per type for example) as this will be relatively slow if carried out for each instance.
Update – Caching
With some example caching of property lookup and ordering:
Update – No Linq
You can replace the Linq section with the following code to order the properties and add them to the cache:
Update – Full Linq
And using a fully Linq solution: