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?
If the issue is, Does the data read into a struct match additional constraints, you will first of all have to figure out how to write down such constraints. (In your example, you wrote [ValidateRange(0,9)] as one such constraint).
Once you have a means to write down the constraints, then you have to presumably read data into corresponding struct and then check the constraints. (In your example, you suggested the idea of using reflection).
It seems to me the easiest way to write down such constraints, that executes fast, is to simply write them as additional C# code. For each constraint you can imagine, you can add a method of the class that checks the constraint and returns a boolean. You can add a standard constraint "CheckIt" that computes a conjunction of all the individual constraint methods.
It should be easy to write the constraints. I'd expect the C# compiler to inline the other methods, especially if they are small and take no arguments (other than the implied class). That should make them fast.
If the C# compiler won't do it, switch to C++, where you can pretty much force inlining.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With