Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将字节数组转换为用户定义的对象?_C#_Casting_Byte_Reinterpret Cast - Fatal编程技术网

C# 如何将字节数组转换为用户定义的对象?

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];

我有课。此对象有两个长度固定的字段(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 };
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;
    }

}