My English skill is poor because I'm not a native English speaker. please understand.
I will tell you about what I want detailly. I created a class below
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class TestClassForNetwork
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11), JsonIgnore]
public byte[] field1;
public short field2;
public short field3;
public short field4;
}
As you know, when deserializing or serializing, I pay attention to converting to a specified endian. so I added the below code.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class TestClassForNetwork
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11), JsonIgnore]
public byte[] field1;
public short field2;
public short field3;
public short field4;
public void ToHostOrder()
{
if (!BitConverter.IsLittleEndian) return;
field2 = IPAddress.NetworkToHostOrder(field2);
field3 = IPAddress.NetworkToHostOrder(field3);
field4 = IPAddress.NetworkToHostOrder(field4);
}
public void ToNetworkOrder()
{
if (!BitConverter.IsLittleEndian) return;
field2 = IPAddress.HostToNetworkOrder(field2);
field3 = IPAddress.HostToNetworkOrder(field3);
field4 = IPAddress.HostToNetworkOrder(field4);
}
}
Here, I thought if it is added the field that has more 2byte, I have to modify ToHostOrder and ToNetworkOrder functions. and this will increase the cost of maintenance.
So I thought the idea was as below.
public void ToHostOrder()
{
if (!BitConverter.IsLittleEndian) return;
// filtering only short type in this class.
FieldInfo[] shortFields;
foreach(var shortField in shortFields)
shortField = IPAddress.NetworkToHostOrder(shortField);
// filtering only int type in this class.
FieldInfo[] intFields;
foreach(var intField in intFields)
intField = IPAddress.NetworkToHostOrder(intField);
}
public void ToNetworkOrder()
{
if (!BitConverter.IsLittleEndian) return;
// filtering only short type in this class.
FieldInfo[] shortFields;
foreach(var shortField in shortFields)
shortField = IPAddress.HostToNetworkOrder(shortField);
// filtering only int type in this class.
FieldInfo[] intFields;
foreach(var intField in intFields)
intField = IPAddress.HostToNetworkOrder(intField);
}
This idea seems to be poor if the count of fields in class is small because the readability is poor but I think this idea will decrease the cost of maintenance if the count of field is bigger because it is no need to worry to convert to a specified endian.
Could someone tell me how to realize this idea?
Thank you for reading.
CodePudding user response:
You can solve this using System.Reflection
and getting all fields of a short
type, and then using GetValue
and SetValue
to get and set the respective fields
In the constructor I set a List of all the fields, so it's only used once. Using System.Linq
's Where
makes sure we only get fields of short
type
public TestClassForNetwork()
{
shortFields = this.GetType().GetFields().Where(field => field.FieldType == typeof(short)).ToList();
}
public List<FieldInfo> shortFields = new List<FieldInfo>();
Taking the same sample fields you have
public byte[] field1;
public short field2;
public short field3;
public short field4;
You can implement ToHostOrder
and ToNetworkOrder
like this
public void ToHostOrder()
{
if (!BitConverter.IsLittleEndian) return;
foreach (var shortField in shortFields)
{
shortField.SetValue(this, IPAddress.NetworkToHostOrder((short)shortField.GetValue(this)));
}
}
public void ToNetworkOrder()
{
if (!BitConverter.IsLittleEndian) return;
foreach (var shortField in shortFields)
{
shortField.SetValue(this, IPAddress.NetworkToHostOrder((short)shortField.GetValue(this)));
}
}
Going forward, you should only need to add new short
fields in your class, for it to be implemented in the methods
CodePudding user response:
you can use MemoryPack library and it can do it for you amazingly with higher performance and code readability.
It doesn't use reflection and all of the stuff is being generated in compile time.
It handles endian and other OS/CPU architecture stuff
It is being maintained by a strong open-source community
It's performance is 50X better than Json or ProtoBuff serialization