I have several c# structs that give shape to structures in a very large data file. These structs interpret bits in the file's data words, and convert them to first-class properties. Here is an example of one:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TimeF1_MsgDayFmt
{
// Time Data Words
public UInt16 TDW1;
public UInt16 TDW2;
public UInt16 TDW3;
/// <summary>
/// Tens of milliseconds
/// </summary>
public UInt16 Tmn
{
// Bits.Get is just a helper method in a static class
get { return Bits.Get(TDW1, 0, 4); }
set
{
if (value > 9)
throw new ArgumentOutOfRangeException();
TDW1 = Bits.Set(TDW1, value, 0, 4);
}
}
/// Several other properties follow.
I need to do two things, which I think are related. The first is to have the ability to validate the entire class, using a collection of validation rules. I know there are several ways to do this; the one that most appeals to me is to annotate each property with something like this:
[ValidateRange(0,9)]
public UInt16 Tmn
{
get { return Bits.Get(TDW1, 0, 4); }
set
{
/// etc. Will probably no longer throw the ArgumentOutOfRangeException here.
... and then use a Validator
class to read all of the property attributes, check each property value against the annotated rule(s), and return a collection of error objects. But I am concerned with how long the Reflection is going to take; these structures have to be extremely high-performing.
public List<Error> Validate(TimeF1_MsgDayFmt original)
The second thing I need to do is to perform auditing on property changes; that is, for each property that has changed from its original value, I need to be able to get a string that says "Property foo changed from bar to baz." To do that, I'd like a way to compare all properties of a "before" and "after" struct
, and note the differences.
public List<string> Compare(TimeF1_MsgDayFmt original, TimeF1_MsgDayFmt new)
In both cases, the code will involve iterating over all of the properties and examining each one individually, in a way that is as fast as possible.
How would I approach this?
Expression
s would be ideal for this. In 3.5, you could either use T4 during compile time or CodeDOM or Reflection.Emit during runtime. – WoadwaxenAre you trying to validate the structures against the actual data?
Yes, to prove the data is correct. The ValidateRange(0,9) attribute is a rule I added that complies with a specification for those particular bits; it doesn't have an implementation yet. – Tangram