如何将字节数组转换为用户定义的对象? [重复]

问题描述 投票:-1回答:2
我上课。该对象有两个长度固定的字段(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 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 };
我该如何去做,或者我需要读什么概念?
c# casting byte reinterpret-cast
2个回答
1
投票
没有从数组直接定义为托管类的强制转换。

正如@ 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; } }


0
投票
我认为您不能直接将arr强制转换为iLink3Message,但是您可以尝试以下解决方案:

我们有SOFHSBEHeader个长度,然后就可以通过使用arrTake函数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();

文档SkipeTake

我希望这会对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.