public IRequest Parse(byte[] dataBytes) { if (dataBytes == null || dataBytes.Length < 9) { throw new CorruptDataException(); } var protocolVersion = dataBytes[0]; if (protocolVersion != 0x00) { throw new NotSupportedProtocolException(protocolVersion); } var requestType0 = dataBytes[1]; var requestType1 = dataBytes[2]; var requestType2 = dataBytes[3]; var requestType3 = dataBytes[4]; if (!_requestTypes.TryGetValue(new RequestTypeAttribute(requestType0, requestType1, requestType2, requestType3), out var requestType)) { throw new UnknownCommandException(); } var dataLength = BitConverter.ToUInt16(dataBytes, 5); var crc0 = dataBytes[7 + dataLength]; var crc1 = dataBytes[8 + dataLength]; var computeChecksum = Crc16.ComputeChecksum(dataBytes.Take(dataBytes.Length - 2)); if (crc0 != computeChecksum[0] || crc1 != computeChecksum[1]) { throw new WrongCrcException(); } var request = Activator.CreateInstance(requestType); var dataIndex = 7; foreach (var propertyInfo in requestType.GetAllProperties()) { object dataValue; (dataValue, dataIndex) = _dataConverterDispatcher.ConvertBack(propertyInfo.PropertyType, dataBytes, dataIndex); propertyInfo.SetValue(request, dataValue); } return((IRequest)request); }