C# 如何将字节数组转换为用户定义的对象?
我有课。此对象有两个长度固定的字段(SOFH和SBHEHeader)和第三个长度可变的字段C# 如何将字节数组转换为用户定义的对象?,c#,casting,byte,reinterpret-cast,C#,Casting,Byte,Reinterpret Cast,我有课。此对象有两个长度固定的字段(SOFH和SBHEHeader)和第三个长度可变的字段 public class iLink3Message { // Simple Open Framing Header (SOFH) public byte[] SOFH { get; set; } = new byte[4]; public byte[] SBEHeader { get; set; } = new byte[8];
public class iLink3Message
{
// Simple Open Framing Header (SOFH)
public byte[] SOFH { get; set; } = new byte[4];
public byte[] SBEHeader { get; set; } = new byte[8];
public byte[] SBEMessage { get; set; }
}
我有一个表示此消息的字节数组。我希望将该字节数组强制转换到此消息中,这样,如果给我以下字节数组,我的对象看起来是这样的:
字节数组
byte[] arr = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e };
ILINK3消息
// Imagine I called the resulting variable iLinkM
iLink3Message iLinkM = (iLink3Message)arr; // or arr as iLink3Message?
iLink3M.SOFH = { 0x01, 0x02, 0x03, 0x04 };
iLink3M.SBEHeader = { 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c};
iLink3M.SBEMessage = { 0x0d, 0x0e };
我怎样才能这样做,或者我需要阅读什么概念?从数组到托管类没有可定义的直接强制转换 正如@Zer0在他的评论中指出的,您可以使用BinaryFormatter,但这将给您一个与您试图转换为/从您的iLink3Message类转换的非常不同的二进制响应,我假设您从一些外部源获得这个字节[],并且不能使用BinaryFormatter 在这种情况下,我将实现自己的cast操作符。以下是完整的源代码,您可以在Main()方法中看到它的用法:
类程序
{
公共类ILink3消息
{
专用字节[]sofh=新字节[4];
专用字节[]sbeHeader=新字节[8];
专用字节[]sbe消息;
公共字节[]SOFH{get{return SOFH;}
公共字节[]SBEHeader{get{return SBEHeader;}}
公共字节[]SBEMessage{get{return SBEMessage;}}
公共静态显式运算符iLink3Message(字节[]缓冲区)
{
if(buffer==null)
{
抛出新的ArgumentNullException(“缓冲区”);
}
如果(缓冲区长度<12)
{
抛出新ArgumentException(“缓冲区必须至少包含12个字节”);
}
iLink3Message castResult=新的iLink3Message();
Array.ConstrainedCopy(buffer,0,castResult.sofh,0,4);
约束复制(缓冲区,4,castResult.sbeHeader,0,8);
castResult.sbeMessage=新字节[buffer.Length-12];
约束复制(buffer,12,castResult.sbeMessage,0,buffer.Length-12);
回归卡斯特罗;
}
公共静态隐式运算符字节[](iLink3Message消息)
{
如果(消息==null)
{
抛出新的ArgumentNullException(“消息”);
}
byte[]castResult=新字节[12+message.sbeMessage.Length];
Array.ConstrainedCopy(message.sofh,0,castResult,0,4);
Array.ConstrainedCopy(message.sbeHeader,0,castResult,4,8);
Array.ConstrainedCopy(message.sbeMessage,0,castResult,12,message.sbeMessage.Length);
回归卡斯特罗;
}
}
静态void Main(字符串[]参数)
{
字节[]arr=新字节[]{0x01、0x02、0x03、0x04、0x05、0x06、0x07、0x08、0x09、0x0a、0x0b、0x0c、0x0d、0x0e};
iLink3Message message=(iLink3Message)arr;
字节[]反向转换=(字节[])消息;
}
}
您不使用内置二进制序列化有什么原因吗?@Zer0您能让我看看这个内置二进制序列化文档吗?请看这个和这个,它们都包含代码。简而言之,您可以将[Serializable]
属性与二进制格式化程序一起使用。如果您需要自定义序列化,我建议您使用ISerializable
。使用互操作封送。固定长度字段可以封装在单独的类型中,然后与最后一个可变长度字段组合。封送处理后,如果由于某种原因无法使用封送处理友好版本,则可以将所有值复制到实际的数据结构中。请参阅标记的副本。
class Program
{
public class iLink3Message
{
private byte[] sofh = new byte[4];
private byte[] sbeHeader = new byte[8];
private byte[] sbeMessage;
public byte[] SOFH { get { return sofh; } }
public byte[] SBEHeader { get { return sbeHeader; } }
public byte[] SBEMessage { get { return sbeMessage; } }
public static explicit operator iLink3Message(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (buffer.Length < 12)
{
throw new ArgumentException("buffer must contain at least 12 bytes");
}
iLink3Message castResult = new iLink3Message();
Array.ConstrainedCopy(buffer, 0, castResult.sofh, 0, 4);
Array.ConstrainedCopy(buffer, 4, castResult.sbeHeader, 0, 8);
castResult.sbeMessage = new byte[buffer.Length - 12];
Array.ConstrainedCopy(buffer, 12, castResult.sbeMessage, 0, buffer.Length - 12);
return castResult;
}
public static implicit operator byte[](iLink3Message message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
byte[] castResult = new byte[12 + message.sbeMessage.Length];
Array.ConstrainedCopy(message.sofh, 0, castResult, 0, 4);
Array.ConstrainedCopy(message.sbeHeader, 0, castResult, 4, 8);
Array.ConstrainedCopy(message.sbeMessage, 0, castResult, 12, message.sbeMessage.Length);
return castResult;
}
}
static void Main(string[] args)
{
byte[] arr = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e };
iLink3Message message = (iLink3Message)arr;
byte[] reverseConversion = (byte[])message;
}
}