Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic casting of unknown types for serialization

I'm writing a custom serializer for struct types for interop with a protocol I can't alter. I'm using reflection to pull out structure member values and write them to a BinaryWriter. It's only designed to support basic types and arrays of them.

if      (fi.FieldType.Name == "Int16")   bw.Write((Int16)fi.GetValue(obj));
else if (fi.FieldType.Name == "UInt16")  bw.Write((UInt16)fi.GetValue(obj));
else if (fi.FieldType.Name == "Int32")   bw.Write((Int32)fi.GetValue(obj));
else if (fi.FieldType.Name == "UInt32")  bw.Write((UInt32)fi.GetValue(obj));
else if (fi.FieldType.Name == "Int64")   bw.Write((Int64)fi.GetValue(obj));
else if (fi.FieldType.Name == "UInt64")  bw.Write((UInt64)fi.GetValue(obj));
else if (fi.FieldType.Name == "Single")  bw.Write((float)fi.GetValue(obj));
else if (fi.FieldType.Name == "Double")  bw.Write((double)fi.GetValue(obj));
else if (fi.FieldType.Name == "Decimal") bw.Write((decimal)fi.GetValue(obj));
else if (fi.FieldType.Name == "Byte")    bw.Write((byte)fi.GetValue(obj));
else if (fi.FieldType.Name == "SByte")   bw.Write((sbyte)fi.GetValue(obj));
else if (fi.FieldType.Name == "String")  bw.Write((string)fi.GetValue(obj));

Obviously this is ugly, and it gets even more ugly when I want to do the same thing with arrays of these types too.

What would be really nice is if I could do something like this:

bw.Write( (fi.FieldType) fi.GetValue(obj) );

Then do a similar kind of thing for arrays.

Any ideas?

like image 648
Polynomial Avatar asked Nov 14 '11 23:11

Polynomial


2 Answers

You can use reflection to invoke the right version of Write

public static void WriteField(BinaryWriter bw, object obj, FieldInfo fieldInfo)
{
    typeof(BinaryWriter)
        .GetMethod("Write", new Type[] { fieldInfo.FieldType })
        .Invoke(bw, new object[] { fieldInfo.GetValue(obj) });
}
like image 99
Jacob Avatar answered Sep 28 '22 08:09

Jacob


This code isn't really ugly at all... it's just repetitive. But it's actually pretty clean, short and very easy to understand. If you had a million different types to account for that would be one thing, but there are only a limited number.

If you are able to do what you're wanting to do, it will be hard to maintain if there's ever a problem with it or it needs to do something more and another programmer may not understand it... or you may have forgotten what the heck you did and have to relearn it.

By doing this you will have: -added additional development time -reduced readability -reduced speed -increased maintenance

Sometimes we like to take problems that are too simple and make them more challenging. But often good business code is just mundane, boring code.

like image 33
Brandon Moore Avatar answered Sep 28 '22 09:09

Brandon Moore