private object ReadValue(MonoTypeEnum type, long addr)
        {
            switch (type)
            {
            case MonoTypeEnum.Boolean:
                return(_view.ReadBool(addr));

            case MonoTypeEnum.U1:
                return(_view.ReadByte(addr));

            case MonoTypeEnum.I1:
                return(_view.ReadSByte(addr));

            case MonoTypeEnum.I2:
                return(_view.ReadShort(addr));

            case MonoTypeEnum.U2:
                return(_view.ReadUshort(addr));

            case MonoTypeEnum.Char:
                return((char)_view.ReadUshort(addr));

            case MonoTypeEnum.I:
            case MonoTypeEnum.I4:
                return(_view.ReadInt(addr));

            case MonoTypeEnum.U:
            case MonoTypeEnum.U4:
                return(_view.ReadUint(addr));

            case MonoTypeEnum.I8:
                return(_view.ReadLong(addr));

            case MonoTypeEnum.U8:
                return(_view.ReadUlong(addr));

            case MonoTypeEnum.R4:
                return(_view.ReadFloat(addr));

            case MonoTypeEnum.R8:
                return(_view.ReadDouble(addr));

            case MonoTypeEnum.Szarray:
                addr = _view.ReadUint(addr);                         // deref object
                var vt        = _view.ReadUint(addr);
                var pArrClass = _view.ReadUint(vt);
                var arrClass  = new MonoClass(_view, pArrClass);
                var elClass   = new MonoClass(_view, _view.ReadUint(pArrClass));
                var count     = _view.ReadInt(addr + 12);
                var start     = addr + 16;
                var result    = new object[count];
                for (var i = 0; i < count; i++)
                {
                    var ea = start + i * arrClass.Size;
                    if (elClass.IsValueType)
                    {
                        if (elClass.ByvalArg.Type == MonoTypeEnum.ValueType)
                        {
                            result[i] = new MonoStruct(_view, elClass, (uint)ea);
                        }
                        else if (elClass.ByvalArg.Type == MonoTypeEnum.GenericInst)
                        {
                            result[i] = new MonoStruct(_view, elClass, (uint)ea);
                        }
                        else
                        {
                            result[i] = ReadValue(elClass.ByvalArg.Type, ea);
                        }
                    }
                    else if (elClass.ByvalArg.Type == MonoTypeEnum.String)
                    {
                        result[i] = ReadValue(elClass.ByvalArg.Type, ea);
                    }
                    else
                    {
                        var po = _view.ReadUint(ea);
                        if (po == 0)
                        {
                            result[i] = null;
                        }
                        else
                        {
                            result[i] = new MonoObject(_view, po);
                        }
                    }
                }
                return(result);

            case MonoTypeEnum.String:
                var pArr = _view.ReadUint(addr);
                if (pArr == 0)
                {
                    return(null);
                }
                var strlen = _view.ReadInt(pArr + 8);
                if (strlen == 0)
                {
                    return(string.Empty);
                }
                var buf = new byte[2 * strlen];
                _view.ReadBytes(buf, 0, strlen * 2, pArr + 12);
                return(Encoding.Unicode.GetString(buf));

            default:
                throw new Exception($"{type} not implemented");
            }
        }