Writing a generic function to validate values translating to enums

  • Thread starter Thread starter Claire
  • Start date Start date
C

Claire

I have a large record with many enumerated fields.
The record is stored in a file and the fields have to be extracted.
I validate the data as it's read, but there's so many tests similar to the
following that I wondered if it's possible to create a single generic
function to perform the validation. Just to keep code size down if nothing
else. I'm not that experienced with .net yet so I don't know what's
possible.

example code
reader is a binaryreader object, all the different enumerated types have an
"Invalid" member which is the final member of the enumeration.

// BaudRate
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eBaudRate.Invalid))
baudRate = eBaudRate.Invalid;
else
baudRate = (eBaudRate)Enum;

//Parity.
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eParity.Invalid))
parity = eParity.Invalid;
else
parity = (eParity)Enum;

// WordLength.
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eWordLength.Invalid))
wordLength = eWordLength.Invalid;
else
wordLength = (eWordLength)Enum;
 
This is an example of how it could be done.

It's using reflection so performance is a bit down, but this could be
optimized a bit. For example the max values could be read just once and
stored in a hashtable and the enumtypes could be stored in variables.

static void Main(string[] args)
{
// BaudRate
Enum = reader.ReadInt16();
baudrate = (eBaudRate)Validate(Enum, typeof(eBaudRate));

//Parity.
Enum = reader.ReadInt16();
parity = (eParity)Validate(Enum, typeof(eParity));

}

public static int Validate(int16 value, type enumType)
{
int max = (int)(Enum.Parse(enumType, "Invalid"));
bool valid = !( value < 0 || value > max );

if (valid)
return value;
else
return max;
}
 
because you're repeating the "reader.ReadInt16();", you could pass in a
valid reader reference to the function...



// BaudRate
baudrate = (eBaudRate)Validate(reader, typeof(eBaudRate));

//Parity.
parity = (eParity)Validate(reader, typeof(eParity));




public static int Validate(BinaryReader reader, type enumType)
{
int readValue = reader.ReadInt16()
int max = (int)(Enum.Parse(enumType, "Invalid"));
bool valid = !( readValue < 0 || readValue > max );

if (valid)
return readValue ;
else
return max;
}


"Patrik Löwendahl [C# MVP]" said:
This is an example of how it could be done.

It's using reflection so performance is a bit down, but this could be
optimized a bit. For example the max values could be read just once and
stored in a hashtable and the enumtypes could be stored in variables.

static void Main(string[] args)
{
// BaudRate
Enum = reader.ReadInt16();
baudrate = (eBaudRate)Validate(Enum, typeof(eBaudRate));

//Parity.
Enum = reader.ReadInt16();
parity = (eParity)Validate(Enum, typeof(eParity));

}

public static int Validate(int16 value, type enumType)
{
int max = (int)(Enum.Parse(enumType, "Invalid"));
bool valid = !( value < 0 || value > max );

if (valid)
return value;
else
return max;
}



--
Patrik Löwendahl [C# MVP]
cshrp.net - 'Elegant code by witty programmers'
cornerstone.se 'IT Training for professionals'
I have a large record with many enumerated fields.
The record is stored in a file and the fields have to be extracted.
I validate the data as it's read, but there's so many tests similar to
the following that I wondered if it's possible to create a single generic
function to perform the validation. Just to keep code size down if
nothing else. I'm not that experienced with .net yet so I don't know
what's possible.

example code
reader is a binaryreader object, all the different enumerated types have
an "Invalid" member which is the final member of the enumeration.

// BaudRate
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eBaudRate.Invalid))
baudRate = eBaudRate.Invalid;
else
baudRate = (eBaudRate)Enum;

//Parity.
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eParity.Invalid))
parity = eParity.Invalid;
else
parity = (eParity)Enum;

// WordLength.
Enum = reader.ReadInt16();
if ((Enum < 0)||(Enum > (byte)eWordLength.Invalid))
wordLength = eWordLength.Invalid;
else
wordLength = (eWordLength)Enum;
 
Back
Top