1 /* Copyright (C) 2007 Versant Inc. http://www.db4o.com */ 2 using System; 3 4 namespace Db4objects.Db4o.Reflect.Net 5 { 6 public class NetArray : Db4objects.Db4o.Reflect.Core.AbstractReflectArray 7 { NetArray(IReflector reflector)8 public NetArray(IReflector reflector) : base(reflector) 9 { 10 } 11 GetNetType(IReflectClass clazz)12 private static Type GetNetType(IReflectClass clazz) 13 { 14 return ((NetClass)clazz).GetNetType(); 15 } 16 Analyze(object obj, ArrayInfo info)17 public override void Analyze(object obj, ArrayInfo info) 18 { 19 info.Nullable(IsNullableType(obj.GetType())); 20 } 21 IsNullableType(Type type)22 private bool IsNullableType(Type type) 23 { 24 if (type.IsArray) 25 { 26 return IsNullableType(type.GetElementType()); 27 } 28 29 Type underlyingType = Nullable.GetUnderlyingType(type); 30 return underlyingType != null; 31 } 32 NewInstance(IReflectClass componentType, ArrayInfo info)33 public override object NewInstance(IReflectClass componentType, ArrayInfo info) 34 { 35 Type type = GetNetType(componentType); 36 if (info.Nullable()) 37 { 38 type = NullableType(type); 39 } 40 MultidimensionalArrayInfo multiDimensionalInfo = info as MultidimensionalArrayInfo; 41 if (multiDimensionalInfo == null) 42 { 43 return System.Array.CreateInstance(type, info.ElementCount()); 44 } 45 int[] dimensions = multiDimensionalInfo.Dimensions(); 46 if (dimensions.Length == 1) 47 { 48 return UnfoldArrayCreation(type, dimensions, 0); 49 } 50 return UnfoldArrayCreation(GetArrayType(type, dimensions.Length - 1), dimensions, 0); 51 } 52 NullableType(Type type)53 private Type NullableType(Type type) 54 { 55 if(IsNullableType(type)) 56 { 57 return type; 58 } 59 return typeof(Nullable<>).MakeGenericType(new Type[] { type }); 60 } 61 NewInstance(IReflectClass componentType, int[] dimensions)62 public override object NewInstance(IReflectClass componentType, int[] dimensions) 63 { 64 Type type = GetNetType(componentType); 65 if (dimensions.Length == 1) 66 { 67 return UnfoldArrayCreation(type, dimensions, 0); 68 } 69 70 return UnfoldArrayCreation(GetArrayType(type, dimensions.Length - 1), dimensions, 0); 71 } 72 UnfoldArrayCreation(Type type, int[] dimensions, int dimensionIndex)73 private static object UnfoldArrayCreation(Type type, int[] dimensions, int dimensionIndex) 74 { 75 int length = dimensions[dimensionIndex]; 76 Array array = Array.CreateInstance(type, length); 77 if (dimensionIndex == dimensions.Length - 1) 78 { 79 return array; 80 } 81 for (int i=0; i<length; ++i) 82 { 83 object value = UnfoldArrayCreation(type.GetElementType(), dimensions, dimensionIndex + 1); 84 array.SetValue(value, i); 85 } 86 return array; 87 } 88 GetArrayType(Type type, int dimensions)89 private static System.Type GetArrayType(Type type, int dimensions) 90 { 91 if (dimensions < 1) throw new ArgumentOutOfRangeException("dimensions"); 92 93 Type arrayType = MakeArrayType(type); 94 for (int i=1; i<dimensions; ++i) 95 { 96 arrayType = MakeArrayType(arrayType); 97 } 98 return arrayType; 99 } 100 MakeArrayType(Type type)101 private static Type MakeArrayType(Type type) 102 { 103 return Sharpen.Lang.ArrayTypeReference.MakeArrayType(type, 1); 104 } 105 NewInstance(IReflectClass componentType, int length)106 public override object NewInstance(IReflectClass componentType, int length) 107 { 108 return System.Array.CreateInstance(GetNetType(componentType), length); 109 } 110 } 111 } 112