/// <summary>
        /// Represents the described multi-dimensional array as array of arrays. Only applicable to array types.
        /// </summary>
        public TypeDescriptor[] MakeRank1Types()
        {
            if (Rank == 0)
            {
                throw new InvalidOperationException("This operation is possible for types with Rank >= 1");
            }

            if (Rank == 1)
            {
                return new TypeDescriptor[] { this }
            }
            ;

            if (!CILType.IsArray)
            {
                throw new InvalidOperationException("This operation is possible for arrays");
            }

            TypeDescriptor[] result    = new TypeDescriptor[Rank];
            Type             innerType = CILType.GetElementType();
            TypeDescriptor   tdElem    = Element0Type;

            for (int i = result.Length - 1; i >= 0; i--)
            {
                innerType = innerType.MakeArrayType();
                result[i] = new TypeDescriptor()
                {
                    _sample = this._sample,
                    CILType = innerType,
                    HasIntrinsicTypeOverride = false,
                    TypeParams      = new object[] { TypeParams[i] },
                    Constraints     = this.Constraints == null ? null : new Range[] { Constraints[i] },
                    IsArtificial    = true,
                    IsUnconstrained = false,
                    Element0Type    = tdElem
                };
                tdElem = result[i];
            }
            return(result);
        }
        private TypeDescriptor GetElement0Type()
        {
            if (_sample == null)
            {
                var etype = CILType.GetElementType();
                return(etype == null ? null : new TypeDescriptor(etype));
            }

            if (CILType.IsArray)
            {
                Array array = (Array)_sample;
                if (array.Length == 0)
                {
                    return(new TypeDescriptor(CILType.GetElementType()));
                }

                object sample = array.GetValue(new int[array.Rank]);
                if (sample == null)
                {
                    return(new TypeDescriptor(CILType.GetElementType()));
                }
                else
                {
                    return(new TypeDescriptor(sample));
                }
            }
            else if (CILType.IsByRef)
            {
                return(new TypeDescriptor(_sample));
            }
            else if (Constraints.Length > 0)
            {
                var indexers = CILType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                               .Where(p => p.GetIndexParameters().Length == Constraints.Length &&
                                      p.GetIndexParameters().All(ip => ip.ParameterType == typeof(int)));
                if (indexers.Any())
                {
                    var indexer = indexers.First();
                    if (Constraints.All(c => c.Size > 0))
                    {
                        object[] index = Constraints.Select(r => (object)r.FirstBound).ToArray();
                        try
                        {
                            var indexSample = indexer.GetValue(_sample, index);
                            return(TypeDescriptor.GetTypeOf(indexSample));
                        }
                        catch (Exception)
                        {
                            return(indexer.PropertyType);
                        }
                    }
                    else
                    {
                        return(indexer.PropertyType);
                    }
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(null);
            }
        }