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 };
iLink3Message
// 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类或从iLink3Message类转换的二进制表示形式非常不同的二进制表示形式,并且我假设您从某个字节中获取了此字节[]。外部源,不能使用BinaryFormatter。
在这种情况下,我将实现自己的演员运算符。这是完整的源代码,您可以在Main()方法中查看其用法:
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;
}
}
arr
强制转换为iLink3Message
,但是您可以尝试以下解决方案:我们有SOFH
和SBEHeader
个长度,然后就可以通过使用arr
和Take
函数Skip
来获取并使用它从Linq
中获取特定值,如以下代码所示:
byte[] arr = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e };
// instantiate the iLink3Message
iLink3Message iLinkM = new iLink3Message();
// get lengths of SOFH and SBEHeader
int sofhLength = iLinkM.SOFH.Length;
int sBEHeaderLength = iLinkM.SBEHeader.Length;
// use skip and take function to get specific values
iLinkM.SOFH = arr.Take(sofhLength).ToArray();
iLinkM.SBEHeader = arr.Skip(sofhLength).Take(sBEHeaderLength).ToArray();
iLinkM.SBEMessage = arr.Skip(sofhLength + sBEHeaderLength).Select(x => x).ToArray();
文档Skipe,Take我希望这会对您有所帮助。