/// <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); } }