I am currently working on a project in which a byte stream of data is to be mapped to properties of an input class. The deserialization code below does its job, but i am not happy with the DeserializeArray() - method. Is there a better and cleaner way to treat array and non array types in a similar way with Reflection.
protected virtual void DoDeserialize(Type aType, object aInstance, PlcBinaryReader aReader)
{
foreach (PropertyInfo p in aType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (p.GetValue(aInstance, null) != null)
{
if (p.PropertyType.IsArray)
DeserializeArray(p, aInstance, aReader); // this method breaks in my eyes the code
else
{
if (p.PropertyType.IsBasicType())
p.SetValue(aInstance, aReader.ReadData(p.PropertyType.Name, GetStrLength(p, false)));
else
DoDeserialize(p.PropertyType, p.GetValue(aInstance, null), aReader);
}
}
}
}
private void DeserializeArray(PropertyInfo aPropInfo, object aInstance, PlcBinaryReader aReader)
{
Array a = (Array)aPropInfo.GetValue(aInstance, null);
IList arr = a;
for (var i = 0; i < a.GetLength(0); i++)
{
Type t = aPropInfo.PropertyType.GetElementType();
if (t.IsBasicType())
arr[i] = aReader.ReadData(t.Name, GetStrLength(aPropInfo, true));
else
DoDeserialize(t, arr[i], aReader);
}
}
private byte GetStrLength(PropertyInfo aPropInfo, bool isArray)
{
byte result = 0;
Type t = isArray ? aPropInfo.PropertyType.GetElementType() : aPropInfo.PropertyType;
if (t.Name == "String")
{
var attr = aPropInfo.GetCustomAttributes(typeof(AdsStringLengthAttribute), true)
.OfType<AdsStringLengthAttribute>().SingleOrDefault();
result = attr != null ? attr.AdsStringLength : Constants.StdAdsStringLength;
}
return result;
}
tia
Aucun commentaire:
Enregistrer un commentaire