I have a little class
public class ExcitingResults
{
public int A { get; set; }
public string B { get; set; }
public DateTime C { get; set; }
public string ComplexD
{
get { return SomeMethod("A", "B"); }
}
}
Currently I do some processing with results a List<ExcitingResults>
that creates JSON or Excel files. This processing relies strongly on the name of each property and the order that things appear in the output is defined by the order they appear in the class. Though in fact this is undefined behaviour and so could change if the compiler decides it wants things in a different order.
For this reason I would like to alter my class to something like this.
public class ExcitingResults
{
public column<int> A { get; set; }
public column<string> B { get; set; }
public column<DateTime> C { get; set; }
public column<string> ComplexD
{
get { return SomeMethod(A.Name, B.Name); }
}
}
public class column<T>
{
public T Value { get; set; }
public string Name { get; set; }
}
Clearly this is not a drop in replacement... is there some clever strategy I can take to make this change as painless as possible. Then in the future add complexity to the Column
class such as order, friendly names and other attributes as they occur to me.
Or is this a crazy way forwards and I should be looking at another strategy to be able to add this extra information to the columns?
You could add property attributes, with the advantage that you don't touch the API of the class. For example, add the class:
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : System.Attribute {
public string FriendlyName { get; set; }
public int Rank { get; set; }
}
You can now annotate your ExcitingResults
class like this:
public class ExcitingResults {
[Column(FriendlyName = "A", Rank = 1)]
public int A { get; set; }
[Column(FriendlyName = "B", Rank = 4)]
public string B { get; set; }
[Column(FriendlyName = "C", Rank = 3)]
public DateTime C { get; set; }
[Column(FriendlyName = "D", Rank = 2)]
public string ComplexD {
get { return SomeMethod("A", "B"); }
}
}
Your processor class can then access the property attributes using reflection. For example, to print out an ExcitingResult
's properties in order of Rank
:
public static void Process(ExcitingResults result) {
var propertiesByRank = typeof(ExcitingResults)
.GetProperties()
.OrderBy(x => x.GetCustomAttribute<ColumnAttribute>().Rank);
foreach (var propertyInfo in propertiesByRank) {
var property = result.GetType().GetProperty(propertyInfo.Name);
var propertysFriendlyName = property.GetCustomAttribute<ColumnAttribute>().FriendlyName;
var propertysValue = property.GetValue(result, null);
Console.WriteLine($"{propertysFriendlyName} = {propertysValue}");
}
}
You'll want to do more error checking in your processing class, but you get the idea. See MSDN documentation and tutorial for more info.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments